我很困惑为什么不同的循环结构在与简单生成器一起使用时表现如此不同。考虑以下代码:
example_list = [1, 2, 3, 4, 5]
for_count = 0
next_count = 0
while_count = 0
def consumer(iterable):
for item in iterable:
yield
return
for item in consumer(example_list):
print("For Count: {0}".format(for_count))
for_count += 1
# First while loop
while consumer(example_list).next():
print("Next Count: {0}".format(next_count))
next_count += 1
# Second while loop
while consumer(example_list):
print("While Count: {0}".format(while_count))
while_count += 1
if while_count > 10: # add contrived limit for infinite loop
break
这段代码的输出是:
For Count: 0
For Count: 1
For Count: 2
For Count: 3
For Count: 4
While Count: 0
While Count: 1
While Count: 2
While Count: 3
While Count: 4
While Count: 5
While Count: 6
While Count: 7
While Count: 8
While Count: 9
While Count: 10
如果能帮助您理解以下内容,我将不胜感激:
for
循环如何知道何时结束而不是第二个while
循环?我预计while
循环会立即退出,因为生成了None
。- 为什么不使用
.next()
引发异常?consumer
例程不是定义了__next__()
方法的类,所以当您使用yield
关键字时它会神奇地出现吗? - 为什么如果我将
consumer
更改为yield item
,第一个while
循环会像第二个一样变成无限循环? - 如果我将
consumer
更改为简单地 return 而不是产生任何东西,第二个while
循环会立即退出而不是变成无限循环。我一直认为yield
本质上是一个return
,您可以从中恢复。为什么while
循环会区别对待它们?
最佳答案
for
循环
您的第一个 for 循环按预期工作。
更新:Mark Ransom请注意,您的 yield
没有附带预期的 item
,因此它只返回 [None, None, None, None, None]
而不是[1, 2, 3, 4, 5]
- 但它仍然遍历列表。
第一个while
循环
The very same commentator还注意到第一个 while 循环永远不会开始,因为 0
在 Python 中是一个 False
等价物。
第二个while
循环
在第二个 while 循环中,您正在测试 consumer(example_list)
的值。这是生成器对象本身,而不是其 next()
返回的值。对象本身永远不会等于 None 或任何其他 False
等价物 - 因此您的循环永远不会结束。
这可以通过在循环内打印 consumer(example_list)
的值(您的 while 条件)看出:
>>> while_count=0
>>> while consumer(example_list):
... print while_count, consumer(example_list)
... while_count += 1
... if while_count > 10:
... break
给予:
0 <generator object consumer at 0x1044a1b90>
1 <generator object consumer at 0x1044a1b90>
2 <generator object consumer at 0x1044a1b90>
3 <generator object consumer at 0x1044a1b90>
4 <generator object consumer at 0x1044a1b90>
5 <generator object consumer at 0x1044a1b90>
6 <generator object consumer at 0x1044a1b90>
7 <generator object consumer at 0x1044a1b90>
8 <generator object consumer at 0x1044a1b90>
9 <generator object consumer at 0x1044a1b90>
10 <generator object consumer at 0x1044a1b90>
第二项是对象,永远不会等于None
。
关于生成器的 Python 循环行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25534862/