生成器在python-2.7.12和python-3.5.2中的不同行为

时间:2019-04-21 06:45:58

标签: python python-3.x python-2.7

对于以下代码,生成器在python2和python3中的行为有所不同。

def g1():
  for i in range(3):
    print("in g1: {}".format(i))
    yield i


def g2():
  for i in range(3):
    print("in g2: {}".format(i))
    yield 2*i


def g3(f1,f2):
  for (i,(x,y)) in enumerate(zip(f1,f2)):
    print("in g3: {} ---- {},{}".format(i,x,y))
    yield (x,y)

h1 = g1()
h2 = g2()

h3=g3(h1,h2)

print(list(h3))

python2的输出

in g1: 0
in g2: 0
in g1: 1
in g2: 1
in g1: 2
in g2: 2
in g3: 0 ---- 0,0
in g3: 1 ---- 1,2
in g3: 2 ---- 2,4
[(0, 0), (1, 2), (2, 4)]

python3的输出

in g1: 0
in g2: 0
in g3: 0 ---- 0,0
in g1: 1
in g2: 1
in g3: 1 ---- 1,2
in g1: 2
in g2: 2
in g3: 2 ---- 2,4
[(0, 0), (1, 2), (2, 4)]

为什么会这样? 需要python3行为。可以在python2中实现吗?

1 个答案:

答案 0 :(得分:3)

在Python 2中,zip不是惰性的,它返回一个列表,并完全消耗其参数。但是,您可以使用izip from itertools模拟Python 3的行为:

from itertools import izip

...
for (i,(x,y)) in enumerate(izip(f1,f2)):
...

在2.7.15上,将zip更改为izip,代码输出:

in g1: 0
in g2: 0
in g3: 0 ---- 0,0
in g1: 1
in g2: 1
in g3: 1 ---- 1,2
in g1: 2
in g2: 2
in g3: 2 ---- 2,4
[(0, 0), (1, 2), (2, 4)]