要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator:
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。
怎么打印出generator的每一个元素呢:使用for
循环
创建一个generator的另一种方法:如果一个函数定义中包含yield
关键字,那么这个函数就不再是一个普通函数,而是一个generator
斐波拉契数列,用函数把它打印出来:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
要把fib
函数变成generator,只需要把print(b)
改为yield b
就可以了:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
变成generator的函数,在每次调用
next()
的时候执行,遇到
yield
语句返回,再次执行时从上次返回的
yield
语句处继续执行。
举个简单的例子,定义一个generator,依次返回数字1,3,5:
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)
调用该generator时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值:
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
要理解generator的工作原理,它是在for
循环的过程中不断计算出下一个元素,并在适当的条件结束for
循环。对于函数改成的generator来说,遇到return
语句或者执行到函数体最后一行语句,就是结束generator的指令,for
循环随之结束。
请注意区分普通函数和generator函数,普通函数调用直接返回结果:
>>> r = abs(6)
>>> r
6
generator函数的“调用”实际返回一个generator对象:
>>> g = fib(6)
>>> g
<generator object fib at 0x1022ef948>
[]是通过遍历可迭代对象生成一个list
()是直接返回可迭代对象
杨辉三角定义如下:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list:
def triangles():result = [1]
while :
yield result
l = list(result)
l.append(0)
result=[l[i]+l[i-1] for i in range(len(l))]
Python实际上调用了list最后一个元素,list每次append的0,在单行计算的开头和结尾用了两次。
路演一下这行代码。。。。。
输出第2层:
l = [1,0]
result = [l[i]+l[i-1] for i in range(len(l))] 的执行顺序:
i = 0
result[0] = l[0]+l[-1] = 1 + 0 = 1
i = 1
result[1] = l[1]+l[0] = 0 + 1 = 1
result = [1,1]
输出第3层:
l = [1,1,0]
result = [l[i]+l[i-1] for i in range(len(l))] 的执行顺序:
i = 0
result[0] = l[0]+l[-1] = 1 + 0 = 1
i = 1
result[1] = l[1]+l[0] = 1 + 1 = 2
i = 2
result[2] = l[2]+l[1] = 0 + 1 = 1
输出第4层:
l = [1,2,1,0]
result = [l[i]+l[i-1] for i in range(len(l))] 的执行顺序:
i = 0
result[0] = l[0]+l[-1] = 1 + 0 = 1
i = 1
result[1] = l[1]+l[0] = 2 + 1 = 3
i = 2
result[2] = l[2]+l[1] = 1 + 2 = 3
i = 3
result[3] = l[3]+l[2] = 0 + 1 = 1
………………