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.count
和 itertools.cycle
都是无限的生成器,因此 zip
将它们连接在一起生成一个 "infinite" 列表。
正如其他人已经提到的,您应该改用 itertools.izip
(仅 Python 2)。
在 Python 2 中,zip
与全局命名空间中的大多数其他 "functional" 元素一样,returns a list
,这意味着它会立即计算所有内容.在 Python 3 中,这将是一个生成器,按需评估,因此需要更少的内存(尽管您提供的输出看起来内存不会成为问题)。
测试代码如下。
在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.count
和 itertools.cycle
都是无限的生成器,因此 zip
将它们连接在一起生成一个 "infinite" 列表。
正如其他人已经提到的,您应该改用 itertools.izip
(仅 Python 2)。
在 Python 2 中,zip
与全局命名空间中的大多数其他 "functional" 元素一样,returns a list
,这意味着它会立即计算所有内容.在 Python 3 中,这将是一个生成器,按需评估,因此需要更少的内存(尽管您提供的输出看起来内存不会成为问题)。