1.数组
mylist = [1, 2, 3]mylist2 = [x*x for x in range(3)]
缺点是所有数据都在内存中,如果有海量数据的话将会非常耗内存。
2.生成器
生成器和数组一样也是可以迭代的,但是用的时候才生成,只可以读取它一次mygenerator = (x*x for x in range(3))
注意,生成器使用了()
3.生成器的执行
mygenerator = (x*x for x in range(3))print(next(mygenerator))print(next(mygenerator))print(next(mygenerator))
运行结果: 0 1 4
生成器通过next()函数进行迭代4.yield关键字
包含yield关键字的函数是生成器,调用时,返回生成器对象。def my_genertor(): a = yield 5 print(a) yieldo = my_genertor()print(next(o))print(next(o))
运行结果 5 None None
分析执行过程: o = my_genertor() 生成器对象next(o)
遇到yield关键字,执行完yield表达式,返回(会保存程序上下文),返回值为表达式结果 因此print(next(o))返回5next(o)
再次执行next()函数,接着上次执行位置,继续执行。将yield语句结果(不是表达式结果),赋值给a变量 next()函数等价于send(None),send函数作用和next函数一致,但是多了一个参数,参数的作用是将参数值赋给yield语句结果 next()参数为None,因此a = yield 5,a为None print(next(o))因为第二个yield表达式为None,因此为None如何返回yield表达式的值?
def my_genertor(): a = yield 5 print(a) yieldo = my_genertor()result = next(o)o.send(result)
将yield表达式的值作为send参数,传递给a变量,因此print(a)结果为5
def my_genertor(): a = yield 5 print(a) yieldo = my_genertor()result = o.send(None)o.send(result)
第一次调用时,必须使用next()或send(None),因为第一次的时候没有上一个yield表达式。
4.yield from
表示调用yield from的函数也是生成器,调用另一个生成器。def fib(n): a = 0 b = 1 for i in range(n): yield b a, b = b, a+bdef copy_fib(n): yield from fib(n)result = fib(5)for item in result: print(item)
运行结果: