简体   繁体   English

Python 2.x和Python 3.x之间的生成器评估差异

[英]Generator evaluation difference between Python 2.x and Python 3.x

Test code could be listed below. 测试代码可以在下面列出。

In Python 2.7.8, this code below caused my machine crashed. 在Python 2.7.8中,下面的代码导致我的机器崩溃。

for row, current_char in zip(cycle(chain(pattern, pattern[::-1][1:][:-1])), count()):
    print row, current_char
    if current_char >= 14:
        break

While in Python 3.2.5.1, the code below works fine. 在Python 3.2.5.1中,下面的代码工作正常。

for row, current_char in zip(cycle(chain(pattern, pattern[::-1][1:][:-1])), count()):
    print(row, current_char)
    if current_char >= 14:
        break

Result is 结果是

0 0
1 1
2 2
1 3
0 4
1 5
2 6
1 7
0 8
1 9
2 10
1 11
0 12
1 13
2 14

Is there anyone knowing the reason? 有谁知道原因? Thanks 谢谢

zip returns an iterator in Python 3, but a list in Python 2. itertools.count and itertools.cycle are both infinite generators, thus zip ping them together produces an "infinite" list. zip在Python 3中返回一个迭代器,但Python 2中的列表itertools.countitertools.cycle都是无限生成器,因此将它们zip在一起会生成一个“无限”列表。

As others already mentioned, you should use itertools.izip instead (Python 2 only). 正如其他人已经提到的那样,你应该使用itertools.izip (仅限Python 2)。

In Python 2, zip like most other "functional" elements in the global namespace, returns a list , meaning it evaluates everything at once. 在Python 2中, zip与全局命名空间中的大多数其他“功能”元素一样,返回一个list ,这意味着它一次评估所有内容。 In Python 3 this will be a generator, evaluated on demand and thus needing less memory (although the output you provided doesn't look like memory would be a problem). 在Python 3中,这将是一个生成器,按需评估,因此需要更少的内存(尽管您提供的输出看起来不像内存会有问题)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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