我很困惑为什么不同的循环结构在与简单生成器一起使用时表现得如此不同。请考虑以下代码:
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
此代码的输出为:
对于伯爵:0 对于伯爵:1 对于伯爵:2 对于伯爵:3 对于伯爵:4 数:0 伯爵:1 伯爵:2 伯爵:3 伯爵:4 伯爵:5 伯爵:6 伯爵:7 伯爵:8 伯爵:9 数:10
我很感激帮助理解以下内容:
for
循环如何知道何时结束但不知道第二个while
循环?我预计两个while
循环会在None
产生后立即退出。.next()
引发异常? consumer
例程不是定义了__next__()
方法的类,因此当您使用yield
关键字时,它会神奇地出现吗?consumer
更改为yield item
,第一个while
循环会变得像第二个循环一样无限?consumer
改为简单地返回而不是产生任何东西,则第二个while
循环立即退出而不是变为无限。我的印象是yield
基本上是return
,您可以从中恢复。为什么while
循环对它们的处理方式不同?答案 0 :(得分:6)
for
循环您的第一个for循环按预期工作。
更新:Mark Ransom注意到您的yield
未附带预期的item
,因此只返回[None, None, None, None, None]
而不是[1, 2, 3, 4, 5]
- 但它仍然遍历列表。
while
循环 The very same commentator也注意到第一个while循环永远不会启动,因为0
是False
- 在Python中等效。
while
循环在第二个while循环中,您正在测试consumer(example_list)
的值。这是生成器对象本身,而不是由next()
返回的值。对象本身永远不等于None或任何其他False
等价物 - 所以你的循环永远不会结束。
通过在循环中打印{while}条件consumer(example_list)
的值可以看出这一点:
>>> 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
。
答案 1 :(得分:1)
仅回答您问题的一部分:
您对while
循环的误解是,while
循环不会像for item in generator
循环一样迭代生成器对象。
第二个while循环中的consumer(example_list)
总是返回一个生成器,它的计算结果为布尔值True,因此循环会永远运行。
在第一个while循环中,您正在测试该生成器的第一个yield值,即None
。因此,循环甚至没有开始。