简体   繁体   中英

Different behavior of generators in python-2.7.12 and python-3.5.2

Generators behave differently in python2 and python3 for the code below.

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))

Output of 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)]

Output of 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)]

Why does this happen? python3 behaviour is desired. Can this be achieved in python2?

In Python 2, zip is not lazy and returns a list, consuming its arguments completely. However, you can simulate Python 3 behavior with izip from itertools :

from itertools import izip

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

On 2.7.15, with zip changed to izip , the code outputs:

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)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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