列表生成式用来生成一个列表,虽然写的是表达式,可是储存的是计算出来的结果,所以生成的列表受到内存大小的限制
示例:python
a = [x ** 2 for x in range(5)] print(a)
输出结果:算法
[0, 1, 4, 9, 16]
生成器一样能够用来生成一个列表,可是生成器保存的是算法,在每一次调用 next
时才会计算出结果,所以生成的列表不会受到内存大小的限制
示例:并发
a = (x ** 2 for x in range(5)) print(a) for i in range(6): print(next(a))
输出结果:函数
<generator object <genexpr> at 0x107da7870> 0 1 4 9 16 Traceback (most recent call last): File "<stdin>", line 2, in <module> StopIteration
每次调用 next()
,就计算出下一个元素的值,没法再次获取前面元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 StopIteration 的错误线程
当函数中出现 yield
时这个函数就成了一个 generator 的函数
generator 在执行的时候遇到 yield
时会暂停并保存当前全部的运行信息,返回 yield
的值, 并在下一次执行 next()
方法时从当前位置继续运行
示例:code
def fib(max_n): """斐波那契数列生成器""" n, a, b = 0, 0, 1 while n < max_n: yield b a, b = b, a + b n = n + 1 return 'done' def main(): f = fib(6) while True: try: x = next(f) print(x) except StopIteration as e: print("Generator return value:", e.value) break if __name__ == '__main__': main()
输出结果:对象
1 1 2 3 5 8 Generator return value: done
示例:内存
import time def consumer(name): print("%s开始吃包子了" % name) while True: produce = yield # 函数在此暂停,等待唤醒 print("%s吃了第%i笼包子" % (name, produce+1)) # 唤醒后执行 def producer(name): c = consumer("A") c2 = consumer("B") c.__next__() c2.__next__() print("%s准备开始生产" % name) for i in range(3): time.sleep(1) print("已经作了%i笼包子" % (i+1)) c.send(i) # 将i发送给produce,并唤醒函数 c2.send(i) producer("C")
输出结果:generator
A开始吃包子了 B开始吃包子了 C准备开始生产 已经作了1笼包子 A吃了第1笼包子 B吃了第1笼包子 已经作了2笼包子 A吃了第2笼包子 B吃了第2笼包子 已经作了3笼包子 A吃了第3笼包子 B吃了第3笼包子
在 producer 函数中 c 和 c2 轮流调用 consumer 函数
send()
和 next()
同样能够唤醒生成器,并且还能给 yield
传值it
能够直接做用于 for 循环的数据类型有如下两种:
示例:
def fib(max_n): """斐波那契数列生成器""" n, a, b = 0, 0, 1 while n < max_n: yield b a, b = b, a + b n = n + 1 return 'done' def main(): f = fib(6) for i in f: print(i) if __name__ == '__main__': main()
输出结果:
1 1 2 3 5 8
能够被 next()
函数调用并不断返回下一个值的对象称为迭代器
生成器都是 Iterator 对象,但list、dict、str 虽然是 Iterable ,却不是Iterator
把list、dict、str 等 Iterable 变成 Iterator 可使用 iter()
函数
示例:
a = [1, 2, 3, 4, 5, 6, 7] b = a.__iter__() c = iter(a) print(a, b, c)
输出结果:
[1, 2, 3, 4, 5, 6, 7] <list_iterator object at 0x11d271f60> <list_iterator object at 0x11d260160>
b, c 都是经过 a 变成的迭代器
a, b, c 均可以使用 for 循环:
for i in a: print(i) for i in b: print(i)
结果一致
生成器 (generator) 都是迭代器 (iterator),可是迭代器不必定是生成器,还有经过 iter()
变成迭代器的可迭代对象