[英]Python Loop Behavior with Generators
我很困惑为什么不同的循环结构在与简单的生成器一起使用时表现得如此不同。 请考虑以下代码:
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
循环处理不同? for
循环 您的第一个for循环可以按预期工作。 更新 : 马克·兰瑟姆 ( Mark Ransom)指出,您的yield
没有预期的item
,因此它只返回[None, None, None, None, None]
而不是[1, 2, 3, 4, 5]
-但仍会迭代名单。
while
循环 同一个评论员也注意到第一个while循环永远不会启动,因为0
在Python中是一个False
等价的。
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
。
仅回答您问题的一部分:
你对while
循环的误解是, while
循环不会自己迭代生成器对象,就像for item in generator
循环中的for item in generator
一样。
第二个while循环中的consumer(example_list)
总是返回一个生成器,它的计算结果为布尔值True,因此循环会永远运行。
在第一个while循环中,您正在测试该生成器的第一个yield值,即None
。 因此,循环甚至没有开始。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.