gpt4 book ai didi

python - 生成器在列表理解中过早结束

转载 作者:太空狗 更新时间:2023-10-29 20:22:17 24 4
gpt4 key购买 nike

我在列表理解中使用生成器,并且其中一个生成器提前结束时出现一些意外行为。为什么在列表理解之外创建生成器会导致行为发生变化?

我创建的生成器如下:

def inc_range(a,b):
for i in range(min(a,b), max(a,b) + 1):
yield i

第一种调用方式如下:

[(i,j) for i in inc_range(1,3) for j in inc_range(4,6)]

这给了我以下结果:

[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]

第二种调用方式如下:

a = inc_range(1,3)
b = inc_range(4,6)

[(i,j) for i in a for j in b]

这给了我以下信息:

[(1, 4), (1, 5), (1, 6)]

四处试验,下面两个例子给了我第一个结果:

a = range(1,4)
b = range(4,7)

[(i,j) for i in a for j in b]
a = (i for i in range(1,4))
b = (i for i in range(4,7))

a = list(a)
b = list(b)

[(i,j) for i in a for j in b]

虽然下面又给了我第二个结果。

a = (i for i in range(1,4))
b = (i for i in range(4,7))

[(i,j) for i in a for j in b]

关于生成器,我在这里违反了什么规则?为什么在列表理解中使用生成器之前将生成器分配给变量与直接使用它们会有所不同?

答案

查看以下帮助我了解此处发生情况的答案:

Alex Yu mkrieger1

最佳答案

为了获得期望的结果,“内部”生成器必须运行与“外部”生成器产生值一样多的次数。

但是,在第一次运行之后,“内部”发电机已经耗尽,无法再次运行。

添加 print 说明了这一点(简化示例):

>>> def inc(a, b):
... for i in range(a, b):
... print(i)
... yield i
...
>>> a = inc(1, 4)
>>> b = inc(4, 7)
>>> [(i, j) for i in a for j in b]
1 # <-- a begins to run
4 # <-- b begins to run
5
6 # <-- b exhausted here
2 # <-- a continued, but not resulting in list item, because lacking value from b
3
[(1, 4), (1, 5), (1, 6)]

之所以没有将生成器存储在变量中按预期工作,是因为为“外部”生成器的每次迭代创建了一个新的“内部”生成器。同样,通过一些打印品说明:

>>> def inc(a, b):
... print('started', a, b)
... for i in range(a, b):
... yield i
...
>>> [(i, j) for i in inc(1, 4) for j in inc(4, 7)]
started 1 4
started 4 7
started 4 7
started 4 7
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]

之所以使用 range 对象或列表能按预期工作,是因为它们可以被任意多次迭代而不会被耗尽。

关于python - 生成器在列表理解中过早结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54895114/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com