繁体   English   中英

生成器的Python循环行为

[英]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

我很感激帮助理解以下内容:

  1. for循环如何知道何时结束而不是第二个while循环? 我期望两个while循环立即退出,因为None得到了。
  2. 为什么不使用.next()引发异常? consumer例程不是定义了__next__()方法的类,因此当您使用yield关键字时,它是否神奇地出现?
  3. 为什么如果我将consumeryield item ,为什么第一个while循环像第二个一样变成无限?
  4. 如果我将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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM