19函数----迭代器(Iterator)

1、可迭代对象(iterable)

可迭代对象都有一个 __iter__() 方法,也就是说有 __iter__() 方法的对象,就是可迭代对象。
'hello'.__iter__
(1,2,3).__iter__
[1,2,3].__iter__
{'a':1}.__iter__
{'a','b'}.__iter__
open('a.txt').__iter__

2、迭代器(iterator)

可迭代对执行obj.__iter__()得到的结果就是迭代器对象
迭代器对象:有__iter__()方法和__next__()方法,当没有数据可用时则将引发 StopIteration 异常。 或:迭代器有两个基本方法: iter() 返回一个迭代器对象, next() 逐一返回迭代对象中的项
文件类型是迭代器对象
from collections import Iterable
from collections import Iterator
open('data.txt').__iter__()
open('data.txt').__next__()
print(isinstance(open('data.txt'), Iterable))
print(isinstance(open('data.txt'), Iterator))

 3、迭代器(协议)的使用

 3.1 通过iter()函数返回可迭代对象的迭代器

from collections import Iterable
from collections import Iterator
dic = {
    'a':1,
    'b':2,
    'c':3,
}
print(isinstance(dic, Iterable))# 判断一个对象是否可以迭代 True
print(isinstance(dic, Iterator))# 判断一个对象是否是迭代器 False
dic_iter = dic.__iter__() #等同于dic_iter = iter(dic)
print(dic_iter)
print(isinstance(dic, Iterable))# 判断一个对象是否可以迭代 True
print(isinstance(dic, Iterator))# 判断一个对象是否是迭代器 True

3.2 for循环

for k in dic: # for循环会自动调用__iter__(),生成一个迭代器
    print(dic[k])
for循环的工作原理
1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
3: 重复过程2,直到捕捉到异常StopIteration,结束循环

3.3 python内置工具中从左到右扫描一个对象的每种工具都使用了迭代协议

    列表解析、in成员测试、map、filter、reduce、enumerate、zip、sorted、sum,any,all,max,min这样的内置函数也都使用了迭代协议。

# map把一个函数应用于可迭代对象的每一项,返回的也是一个可迭代对象,而不是列表,
res = list(map(lambda x:x+3, range(3))) #[3, 4, 5]
m = list(map(abs,(-1,0,1))) #[1, 0, 1]
# zip组合可迭代对象中的各项,返回的也是一个可迭代对象
res = list(zip((1,2,3),('a','b','c'))) #[(1, 'a'), (2, 'b'), (3, 'c')]
# enumerate根据相对位置来配对可迭代对象中的项,返回的也是一个可迭代对象
res = list(enumerate(range(3))) #[(0, 0), (1, 1), (2, 2)]
# filter函数会返回参数函数返回值为True的每一项,返回的也是一个可迭代对象
res = list(filter(lambda x:x.startswith('a'),['abc','cd','d'])) #['abc']
# reduce针对可迭代对象中的成对的项运行一个函数
from functools import reduce
res1 = reduce(lambda x,y:x+y,[1,2,3,4,5])# # 计算列表和:1+2+3+4+5 = 15
res2 = reduce(lambda x,y:x+y,[1,2,3,4,5],100)# # 计算列表和:1+2+3+4+5,同时初始值为100,得115

# sorted 排序可迭代对象中的各项,返回一个列表
# sum 计算可迭代对象中的总数
# all、any,如果一个可迭代对象中任何的所有的项为真,则返回True
res1 = all(['a','','c']) #False
res2 = any(['a','','c']) #True
# max、min 返回可迭代对象中的最大、最小项,也可以应用于文件

# 甚至:list()、tuple()内置函数,join(),也是使用了迭代协议,函数中*arg也可以接受任何的可迭代对象
# 字典方法keys,values,items,也是返回可迭代对象

 4、迭代器的优缺点

优点:1、提供了不依赖于索引的迭代方式(字典、集合、文件就没有索引)
2、惰性计算,只在需要时才调用__next__()方法获得下个值,同一时刻内存中只有一个值,可以存放无限大的数据
缺点:1、除非取尽,否则不能获得长度
2、不能回头

 

posted @ 2021-04-03 18:03  cheng4632  阅读(289)  评论(0编辑  收藏  举报