- 列表生成式
a=[i*2 for i in range(10)] print(a) >>> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
- 迭代器&生成器
生成器(generator):
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器。
只有在调用时才会生成相应的数据
方法一:
a=[i*2 for i in range(10)] print(a) >>>
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
把一个列表生成式的[]
改成()
a=(i*2 for i in range(10)) print(a) >>> <generator object <genexpr> at 0x05482570>
调用方法:a.__next()__
print(next(a)) print(next(a)) >>> 0 2
or
for i in a: print(i) >>> 0 2 4 6 8 10 12 14 16 18
方法二:
斐波那契数列(Fibonacci):除第一个和第二个数外,任意一个数都可由前两个数相加得到
def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done'
赋值语句:
a, b = b, a + b
相当于:
t = (b, a + b) # t是一个tuple a = t[0] b = t[1]
将函数中print(b)改为yield b
就变成了生成器
def fib(max): n,a,b = 0,0,1 while n < max: #print(b) yield b a,b = b,a+b n += 1 return 'done' f=fib(5) print(f) print(f.__next__()) print(f.__next__()) print(f.__next__()) print(f.__next__()) >>> <generator object fib at 0x05792570> 1 1 2 3
for i in f: print(i) >>> 1 1 2 3 5
但是用for
循环调用generator时,发现拿不到generator的return
语句的返回值。如果想要拿到返回值,必须捕获StopIteration
错误,返回值包含在StopIteration
的value
中:
g = fib(6) while True: try: x = next(g) print('g:', x) except StopIteration as e: print('Generator return value:', e.value) break >>> g: 1 g: 1 g: 2 g: 3 g: 5 Generator return value: done
- 迭代器