可迭代对象:一个实现了iter方法的对象是可迭代的
迭代器:一个实现了iter方法和next方法的对象就是迭代器
生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable(可迭代对象)
,却不是Iterator(迭代器)
。
from collections import Iterator #迭代器 from collections import Iterable #可迭代对象 print(isinstance(s,Iterator)) #判断是不是迭代器 print(isinstance(s,Iterable)) #判断是不是可迭代对象 #把可迭代对象转换为迭代器 print(isinstance(iter(s),Iterator))
为什么list
、dict
、str
等数据类型不是Iterator
?
这是因为Python的Iterator
对象表示的是一个数据流,Iterator对象可以被next()
函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()
函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
生成器:生成器是迭代器的一种
创建生成器的方法有两种:
1.把一个列表生成式的[]中括号改为()小括号
a = [i+1 for i in range(5)] # 列表生成式 print(a) b = (i+1 for i in range(5)) # 生成器 print(b) print(next(b)) print(next(b)) print(next(b)) print(next(b)) print(next(b)) print(next(b)) 输出结果: [1, 2, 3, 4, 5] <generator object <genexpr> at 0x00000163C820BAF0> 1 2 3 4 5 Traceback (most recent call last): File "E:/myproj/pytest_demo/b.py", line 13, in <module> print(next(b)) StopIteration
生成器最常用的还是通过for循环调用:
for i in b:
print(i)
2.定义一个包含yield语句的函数,通过调用该函数得到生成器
def fib(max): n,a,b =0,0,1 while n < max: yield b a,b =b,a+b n = n+1 return ‘done‘ a =fib(6) # 调用包含yield语句的函数并不会立即执行,它只是返回一个生成器,只有当程序通过next()函数调用或者遍历生成器时,函数才会真正执行 print(a) for i in fib(6): print(i) 输出结果: <generator object fib at 0x000001866F62BAF0> 1 1 2 3 5 8
关于yield:
与return类似,程序执行到yield会返回,等再次调用时,程序从上次yield处继续往下执行
如果对以上运行原理还是不清楚,可以通过debug示例代码进一步理解...
原文:https://www.cnblogs.com/wang-mengmeng/p/11440165.html