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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (554)

如何在Python的列表推导中执行以下操作?

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发生,就将列表的其余部分清零。

提问于
用户回答回答于

这是一个线性时间解决方案,它不会改变全局状态,不需要除了之外的任何其他迭代器nums,并且可以执行您想要的操作,尽管需要一些辅助数据结构,并使用严重的列表理解:

>>> nums = [1,1,0,1,1]
>>> [f for f, ns in [(1, nums)] for n in ns for f in [f & (n==1)]]
[1, 1, 0, 0, 0]

不要用这个。使用原始for循环。它更具可读性,几乎肯定更快。不要努力将所有内容都放在列表理解中。努力使您的代码简单,可读和可维护,您的代码已经是,而上面的代码不是。

用户回答回答于

在某些上下文中,列表理解是许多函数式编程语言中存在的函数mapfilter函数的一种“命令式”语法。你想要做的通常被称为a accumulate,这是一个稍微不同的操作。除了使用副作用之外,您无法实现accumulatea mapfilter。Python允许你从列表理解中获得副作用,所以它绝对可能,但是带有副作用的列表推导有点不稳定。以下是使用accumulate实现此方法的方法:

nums = [1,1,0,1,1]

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

list(accumulate(nums, accumulator))

或者在一行中:

list(accumulate(nums, lambda last, cur: 1 if (last == 1 and cur == 1) else 0))

当然,有几种方法可以使用外部状态和带有副作用的列表理解来完成此操作。这是一个例子,它有点冗长,但非常清楚如何操纵状态:

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]

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励