【问题标题】:Python: Generator that yields lists, problems with list() and list comprehension [duplicate]Python:生成列表的生成器,list() 和列表理解的问题 [重复]
【发布时间】:2018-04-20 03:40:11
【问题描述】:

假设我想编写一个生成器,它返回列表,例如迭代列表排列。举个简单的例子:

def list_gen():
    foo = [1,2,3,4]
    for i in range(5, 9):
        foo[1] = i
        yield foo


bar = list(list_gen())
print(bar)
bar = [l for l in list_gen()]
print(bar)

for l in list_gen():
    print(l, end=' ')

输出是:

[[1, 8, 3, 4], [1, 8, 3, 4], [1, 8, 3, 4], [1, 8, 3, 4]]
[[1, 8, 3, 4], [1, 8, 3, 4], [1, 8, 3, 4], [1, 8, 3, 4]]
[1, 5, 3, 4] [1, 6, 3, 4] [1, 7, 3, 4] [1, 8, 3, 4] 

所以对于 for 循环,一切都按预期工作,但对于 list() 或列表推导,所有值都等于最后一个。据我了解,这是因为列表是可变的,并且 bar 的所有元素都指向同一个对象。

一种可能的解决方法是bar = [list(l) for l in list_gen()],但它看起来相当难看。有没有更好的方法来处理这个问题?

【问题讨论】:

  • 是的。不要生成相同的列表...

标签: python list generator mutable


【解决方案1】:

针对这个特定问题的一个简单解决方案是返回一个新列表,而不是 foo 对象。

def list_gen():
    foo = [1,2,3,4]
    for i in range(5, 9):
        foo[1] = i
        yield list(foo)

免责声明:我不经常使用生成器,因此这可能违反最佳做法。但它解决了问题。

【讨论】:

  • 如果你想将每个循环的foo 的值重置回[1,2,3,4],你可以将它移到for 循环中。以防将来您不希望更改在每个 yield 之间持续存在。
  • 嗨@ZeitPolizei - 如果这解决了您的问题,您可以将问题标记为已解决吗?
猜你喜欢
  • 1970-01-01
  • 2016-02-06
  • 2020-07-19
  • 2016-10-04
  • 2016-09-13
  • 2013-12-30
  • 1970-01-01
  • 2014-08-28
相关资源
最近更新 更多