可迭代对象、迭代器、生成器
可迭代对象
-
可迭代对象(对象:python中一切皆对象,一个实实在在存在的值,对象。迭代:重复的,循环的一个过程,更新迭代每一次都有新的内容)
- 字面意思
- 可以进行循环更新的一个实实在在的值
- 专业角度
- 内部含有
__iter__
方法的对象,被成为可迭代对象
- 内部含有
- 字面意思
-
获取对象的所有方法并且以支付串的形式表示
-
dir()
-
判断一个对象是否是可迭代对象
#方法一 s1='ghj' s=dir(s1) for i in s: if "iter" in i: print('ok') #方法二 print('__iter__' in dir('fghj'))
-
-
小结
- 优点:
- 存储的对象直接能显示,比较直观
- 拥有的方法比较多,操作方便
- 缺点:
- 占内存
- 不能直接通过for循环,不能直接取值(索引,key除外)
- 优点:
迭代器
-
迭代器的定义(器:可更新迭代的工具。)
- 字面意思:可更新迭代的工具
- 专业角度:内部含有
__iter__
方法并且含有__next__
方法的对象就是迭代器
-
可以判断是否是迭代器
__iter__
and__next__
在不在dir(对象 )-
with open('简单',encoding='utf-8',mode='r')as f1: print('__iter__'in dir(f1)and'__next__' in dir(f1))
-
-
迭代器取值
-
s='ghjkl' a=iter(s) print(next(a)) print(next(a)) print(next(a))
-
-
可迭代对象转换成迭代器
1.iter(可迭代对象)
-
while循环模拟for 循环机制
s=[11,22,33,44,55,66] a=iter(s) while True: try: print(next(a)) except StopIteration: break
-
小结(优缺点)
- 优点:
- 节省内存
- 惰性机制(next一次取一个值,绝对不多取)
- 迭代时数据处理的基石,扫描内存中放不下的数据集时,我们要找到一种惰性获取数据的方式,即按需一次获取一个数据项,这就是迭代器模式。
- 缺点:
- 速度慢
- 不走回头路
- 优点:
可迭代对象和迭代器对比
- 可迭代对象
- 可迭代对象是一个操作方法比较多,比较直观,存储数据相对少的一个数据集(几百万数据8G内存是可以承受的)
- 应用:当侧重于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择
- 迭代器
- 迭代器是一个节省内存,可以记录取值的位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集
- 应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为主要因素时,将数据集设置为迭代器是一个不错的选择(可以参考python为什么把文件句柄设置为迭代器)
生成器
-
什么是生成器
- python社区,生成器与迭代器看成是一种。生成器的本质就是迭代器。
- 生成器与迭代器的区别:生成器是我们自己用代码构建的一种数据结构,迭代器都是提供或者转化过来的。
-
获取生成器的三种方式
-
生成器函数
-
return和yield的区别:
- return:函数中只存在一个return结束函数并且给函数的执行者返回值
- yield:只要函数中有yield那么它就是生成器而不是函数了
- 生成器函数中可以存在多个yield,yield不会结束生成器函数,一个yield对应一个next。
- 生成yield函数以上得代码会执行,以下的代码则不会执行
def func(): print('aaa') print('bbb') yield 3 print('ccc') yield 6 print('ddd') ret=func() print(next(ret)) print(next(ret)) 得: aaa bbb 3 ccc 6
-
-
生成器表达式
- 不用一次性全取,需要多少取多少
def bao(): for i in range(1,201): yield i ret=bao() for j in range(50): print(next(ret))
-
python内部提供的一些
-
-
yeild form
- yield from 将l1这个列表变成迭代器返回
def func(): li=[11,22,33,44] yield from li #yield from 将l1这个列表变成迭代器返回 ret=func() print(next(ret))
-
生成器表达式
- 与列表推导式的写法几乎一模一样
obj=(i for i in range(1,11)) for j in obj: #for 循环的时候就已经转换成迭代器 print(j) obj=(i for i in range(1,11)) print(next(obj)) print(next(obj)) print(next(obj))