1. 生成器
- 通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个 包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数 的元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的 过程中不断推算出后续的元素呢?这样,就不必创建完整的list,从而节省大量的空间。
- 在Python中,这种一边循环一边计算的机制,称为生成器(generator)
# 列表生成式,值一下子,全部计算出来:L = [ x*2 for x in range(5)]L # 输出: [0, 2, 4, 6, 8]# 创建生成器, 列表元素是推算出来的:G = ( x*2 for x in range(5))G # 输出:at 0x1077d9db0>next(G) # 每执行一次 next(),输出一个元素, 等价于 G.__next__(), Python 2.x : G.next()# 创建生成器的第二种方式: 使用函数(yield 关键字)# 斐波拉契数列(Fibonacci)def fib(times): n = 0 a, b = 0, 1 while n < times: print(b) a, b = b, a+b n += 1 return 'done'fib(5)# 生成器(ipython 中操作)def fib(): print("=== start ===") a, b = 0, 1 for i in range(5): print("=== 1 ===") yield b print("=== 2 ===") a, b = b, a+b print("=== 3 ===") print("=== stop ===")a = fib()a # 输出: next(a) # 等价于 a.__next__()# 输出:# === start ===# === 1 ===# 1# 此时,fib()函数就是生成器,可以使用循环来迭代for num in a: print(num)
1.1 send 方法
# 示例:# ipython3 中操作def gen(): i = 0 while i<5: temp = yield i print(temp) i+=1a = gen()a.__next__() # 输出: 0a.__next__() # 输出: Nonec = a.send("haha") # 输出: hahaprint(c) # 输出: 2# 说明: 程序执行到yield时,gen函数暂时停止,同时返回i的值;# temp 接收send过来的值(haha);# a.__next__() 等价 a.send(None)# 若是第一次直接调用 a.send("haha"), 程序会报错
2. 迭代器
- 迭代是访问集合元素的一种方式。
- 迭代器是一个可以记住遍历的位置的对象;
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束;
- 迭代器只能往前不会后退;
2.1 可迭代对象
- 可以直接作用于 for 循环的数据类型有以下几种:
- 集合数据类型:
list
,tuple
,dict
,set
,str
等; generator
, 包括生成器和带yield
的generation function
;- 这些可以直接作用于for循环的对象统称为可迭代对象(Iterable)
- 集合数据类型:
- 可以使用
isinstance()
判断一个对象是否是Iterable
对象; - 拥有内置方法
__iter__()
;
# 示例:from collections import Iterableisinstance([], Iterable) # True
2.2 迭代器
- 可以被
next()
函数调用并不断返回下一个值的对象称为迭代器(Iterator); - 可以使用
isinstance()
判断一个对象是否是 Iterator 对象;
# 示例:from collections import Iteratorisinstance((x for x in range(10), Iterator) # Trueisinstance([], Iterator) # False
2.3 iter()函数
- 生成器都是 Iterator 对象;
list
,dict
,str
虽然是 Iterable,却不是 Iterator;- 可以使用
iter()
函数把list
,dict
,str
等 Iterable 变成 Iterator;
# 示例:from collections import Iteratorisinstance(iter([]), Iterator) # True
参考资料: