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

Generator evaluation difference between Python 2.x and Python 3.x

测试代码如下。

在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

在 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

结果是

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

有谁知道原因吗?谢谢

zip returns Python 3 中的迭代器,但 Python 2 中的列表。 itertools.countitertools.cycle 都是无限的生成器,因此 zip将它们连接在一起生成一个 "infinite" 列表。

正如其他人已经提到的,您应该改用 itertools.izip(仅 Python 2)。

在 Python 2 中,zip 与全局命名空间中的大多数其他 "functional" 元素一样,returns a list,这意味着它会立即计算所有内容.在 Python 3 中,这将是一个生成器,按需评估,因此需要更少的内存(尽管您提供的输出看起来内存不会成为问题)。