Python基础---生成器Generator & 迭代器Iterator
生成器Generator & 迭代器Iterator
迭代器Iterator:
迭代是一种访问集合元素的方式;
可迭代对象Iterable:可以直接作用于for循环的对象都可以成为可迭代对象
迭代器是可以被next()函数调用并不断返回下一个值的对象;
迭代器对象从集合的第一个元素开始访问,直到所有元素访问完毕。迭代器只能往前不能后退
迭代器基本的方法:iter()、next()
1 a = [1, 2, 3, 4] 2 b = iter(a) # iter()方法:将一个可迭代对象转换成迭代器 3 print(next(b)) # next()方法:不断调用迭代器,并返回下一个值 4 print(next(b)) 5 print(next(b)) 6 print(next(b)) 7 8 --->1 9 --->2 10 --->3 11 --->4
迭代器也可以使用for循环遍历:
1 a = [1, 2, 3, 4] 2 b = iter(a) 3 for x in b: 4 print(x, end=' ')
5
6 --->1 2 3 4
集合数据类型list、dict、str等可迭代对象不是迭代器
1 from collections import Iterator 2 x = isinstance([], Iterator) # isinstance()方法:判断一个对象的type,返回bool值,比type()更节省资源 3 print(x) 4 --->False 5 x = isinstance({}, Iterator) 6 print(x) 7 --->False 8 x = isinstance(str, Iterator) 9 print(x)
10 --->False
这是因为Python的迭代器Iterator对象标识的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据当作一个有序序列,但是不知道其长度,只能通过不断的next()函数实现 按需计算 下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时,Iterator才会计算。
生成器Generator:
在Python中,使用了yield关键字的函数可以被称为生成器;
生成器是一个返回迭代器的函数,只能用于迭代操作;
生成器相比其他容器对象,更能节省内存和CPU;
生成器一定是迭代器,反之则不成立
执行流程:在调用生成器运行的过程中,每次遇到yield时,函数会暂停并保存当前所有运行信息,返回yield的值,并在下次执行next()函数时从当 前位置开始
创建一个生成器:
1、最简单的,只需要把一个列表生成式的 [ ] 改成 ( ) 即可:
1 a = (x ** 2 for x in range(1, 10)) 2 print(a, type(a)) 3 for x in a: 4 print(x, end=' ') 5 ---><generator object <genexpr> at 0x05AA4E70> <class 'generator'> 6 --->1 4 9 16 25 36 49 64 81
2、也可以使用yield来创建生成器函数:(如果推算的比较复杂,使用第一种方法无法创建的时候,如斐波拉契数列)
1 num = [] # 创建一个包含所有自然数的生成器;自然数为大于零的整数,无穷个, 2 # list因为内存受限,容量肯定是有限的,所以可以使用生成器,按需取用
3 4 def append_num(n): 5 while True: 6 if n > 0: 7 num.append(n - 1) 8 yield num 9 n += 1 10 else: 11 return False 12 13 14 x = append_num(1)
1 def fib(m): # 生成斐波拉契数列的前m个数字 2 n, a, b = 0, 0, 1 # 相当于 t = (b, a + b) a = t[0] b = [1] 不必写出临时变量t,直接赋值 3 while n < m: 4 yield b 5 a, b = b, a + b 6 n += 1 7 8 9 x = fib(10) 10 for y in x: 11 print(y, end=' ') 12 --->1 1 2 3 5 8 13 21 34 55
1 def triangles(): # 设计杨辉三角,不断输出下一行的list 2 L = [1] # 设定默认值 3 n = [] 4 while True: 5 yield L # 输出L 6 for x in range(len(L)-1): # range(len(L) - 1) 遍历L列表长度-1的数字列表,是为了下一行代码中,不让程序利用L列表最后一位元素 7 n.append(L[x] + L[x + 1]) # 将上一个L列表相邻的两个元素的和添加入n列表 8 L = [1] + n + [1] # 进行组合,首尾各添加一个元素 1 9 n = [] # 每次计算后,初始化n列表 10 11 12 results = [] 13 n = 0 14 for y in triangles(): 15 print(y) 16 results.append(y) 17 n = n + 1 # 控制条件,因为triangles()代表着一个无限大的杨辉三角,没有控制条件会出现无限遍历 18 if n == 10: 19 break 20 21 [1] 22 [1, 1] 23 [1, 2, 1] 24 [1, 3, 3, 1] 25 [1, 4, 6, 4, 1] 26 [1, 5, 10, 10, 5, 1] 27 [1, 6, 15, 20, 15, 6, 1] 28 [1, 7, 21, 35, 35, 21, 7, 1] 29 [1, 8, 28, 56, 70, 56, 28, 8, 1] 30 [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]


浙公网安备 33010602011771号