首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python的列表理解:如果出现某个值,则修改列表元素

Python的列表理解:如果出现某个值,则修改列表元素
EN

Stack Overflow用户
提问于 2018-09-20 05:34:54
回答 4查看 3.2K关注 0票数 9

如何在Python的列表理解中执行以下操作?

代码语言:javascript
复制
nums = [1,1,0,1,1]
oFlag = 1
res = []
for x in nums:
    if x == 0:
        oFlag = 0
    res.append(oFlag)
print(res)

# Output: [1,1,0,0,0]

实际上,在本例中,一旦发生0,列表的其余部分就会清零。

EN

回答 4

Stack Overflow用户

发布于 2018-09-20 06:00:34

在某些上下文中,列表理解是存在于许多函数式编程语言中的mapfilter函数的一种“命令式”语法。您尝试执行的操作通常称为accumulate,这是一个稍有不同的操作。您不能用mapfilter来实现accumulate,除非使用副作用。Python允许你在列表理解中有副作用,所以这绝对是可能的,但是有副作用的列表理解有点不可靠。下面是如何使用accumulate实现此功能:

代码语言:javascript
复制
nums = [1,1,0,1,1]

def accumulator(last, cur):
    return 1 if (last == 1 and cur == 1) else 0

list(accumulate(nums, accumulator))

或者一行:

代码语言:javascript
复制
list(accumulate(nums, lambda last, cur: 1 if (last == 1 and cur == 1) else 0))

当然,有几种方法可以使用外部状态和带有副作用的列表理解来做到这一点。这里有一个例子,它有点冗长,但非常明确地说明了状态是如何被操纵的:

代码语言:javascript
复制
class MyState:
    def __init__(self, initial_state):
        self.state = initial_state
    def getNext(self, cur):
        self.state = accumulator(self.state, cur)
        return self.state

mystate = MyState(1)
[mystate.getNext(x) for x in nums]
票数 8
EN

Stack Overflow用户

发布于 2018-09-20 06:06:13

我有一个使用列表理解的答案,但@Prune抢先了我一步。这真的只是一条警示的尾巴,显示了如何在反对该方法的同时完成它。

以下是一种可能适合您需求的替代方法:

代码语言:javascript
复制
import itertools
import operator

nums = [1,1,0,1,1]
res = itertools.accumulate(nums, operator.and_)

在本例中,res是一个可迭代的。如果你需要一个列表,那么

代码语言:javascript
复制
res = list(itertools.accumulate(nums, operator.and_))

让我们来分析一下。accumulate()函数可用于生成运行总数或“累积和”。如果只传递了一个参数,则默认函数为addition。这里我们传入operator.and_。operator模块导出一组与Python的内部运算符相对应的高效函数。当在0和1的列表上运行累加的and时,结果是一个列表,在找到第一个0之前是1,然后是所有0。

当然,我们并不局限于使用operator模块中定义的函数。您可以使用任何接受第一个参数中元素类型的2个参数的函数(并且可能返回相同的类型)。您可以发挥创造力,但在这里我将保持简单,只实现and

代码语言:javascript
复制
import itertools

nums = [1,1,0,1,1]
res = itertools.accumulate(nums, lambda a, b: a and b)

注意:使用operator.and_可能运行得更快。在这里,我们只是提供一个使用lambda语法的示例。

虽然没有使用列表理解,但对我来说有类似的感觉。它只有一行,读起来不是很难。

票数 5
EN

Stack Overflow用户

发布于 2018-09-20 05:39:25

对于列表理解方法,您可以结合使用indexenumerate

代码语言:javascript
复制
firstIndex = nums.index(0) if 0 in nums else -1
[1 if i < firstIndex else 0 for i, x in enumerate(nums)]

另一种使用numpy的方法

代码语言:javascript
复制
import numpy as np
print(np.cumprod(np.array(nums) != 0).tolist())
#[1, 1, 0, 0, 0]

在这里,我们将nums转换为numpy数组,并检查这些值是否不等于0。然后我们得到数组的累积乘积,知道一旦找到0,我们就会从那个点开始乘以0。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52414505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档