Day 13
迭代器(for, list, tuple, dict, set)
1、什么是迭代器
器:工具
迭代:重复的过程,每次重复都是基于上次的结果而来的
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。
内置__iter__
方法的类型:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UYdoBE3r-1595415360570)(C:%5CUsers%5CS%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20200722101446785.png)]
2、为何要有迭代器
找到一种不依赖索引的迭代取值的方法,自定义迭代器来实现惰性计算,从而达到节省内存的效果
但凡是函数内出现了yield
关键字调用函数将不会执行函数体代码,会得到一个返回值,该返回值就是我们自定义的迭代器,称之为生成器
总结迭代器的优缺点
优点:
1、是一种通用的迭代器取值方取值案
2、惰性计算,节省内存
缺点:
1、取值不如索引,key的取值方式灵活
2、取值是一次性的,只能往后取,不能预估值的个数
3、迭代和迭代器:
迭代:凡是可作用for
循环的对象都成为迭代
迭代器:可以被next()
函数调用并不断返回下一个值的对象
区别:集合类型list, dict, str
是迭代但不是迭代器!
for 循环和 迭代器的区别
4、如何用迭代器
迭代器的工作机制
迭代器也可以说是迭代器对象,具有__iter__
方法的对象调用__iter__
会返回一个迭代器对象
4.1 迭代器的引入
dic = {"name": "egon", 'age': 18, 'gender': "male"}
res1 = dic_iterator.__next__()
print(res1) # name
res2 = dic_iterator.__next__()
print(res2) # age
res3 = dic_iterator.__next__()
print(res3) # gender
res4 = dic_iterator.__next__()
print(res4) # erro StopIteration
4.2可迭代对象与迭代器对象
4.2.1 内置有__iter__方法的类型称之为:可迭代的对象/类型
1> 字典dict
2> 集合set
3> 文件对象(也是迭代器对象)
4> 字符串str
5> 列表list
6> 元组tuple
4.2.2 迭代器对象: 内置有__next__方法、内置有__iter__方法
print(dic_iterator1.__iter__().__iter__().__iter__() is dic_iterator1)
res1 = dic_iterator.__iter__()
res2 = res1.__iter__()
print(res1) # <str_iterator object at 0x000001D7BC22BE10>
print(res2) # <str_iterator object at 0x000001D7BC22BE10>
res3 = res2.__iter__()
print(res3) # <str_iterator object at 0x000001D7BC22BE10>
调用 iter方法,返回自身self,也就是返回迭代器。
5、for 循环的工作机制
当对象本身就是迭代器时,For循环工作机制:
调用 __iter__方法,返回自身self,也就是返回迭代器。不断地调用迭代器的next()方法,每次按序返回迭代器中的一个值。迭代到最后没有元素时,就抛出异常 StopIteration
在可迭代对象中,for循环工作机制:
先判断对象是否为可迭代对象(等价于判断有没有__iter__或__getitem__方法),没有的话直接报错,抛出TypeError异常。有的话,调用 __iter__方法,返回一个迭代器。在python内部不断地调用迭代器的__next__方法,每次按序返回迭代器中的一个值。迭代到最后没有元素时,就抛出异常 StopIteration,这个异常 python 自己会处理,不会暴露给开发者。
6、生成器(yeild)
1、什么是生成器
但凡是函数内出现了yield关键字,调用函数将不会执行函数体代码,会得到一个返回值,该返回值就是我们自定义的迭代器,称之为生成器
2、yeild VS return
(1)相同点:都可以用来返回值
(2)不同点:
return只能返回一次值,函数就立即结束了
yield能返回多次值,yield可以挂起函数
def range1(start, end=100, sep=1):
while start < end:
yield start
start += sep
g = range1(10, sep=5)
print(next(g), end="\t") # 10
print(next(g), end="\t") # 15
print(next(g), end="\t") # 20
print()
for i in g:
print(i, end="\t") # 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
返回当生成器 g
的函数被next
生成后 生成器中将不再有 生成的数据
7、面向过程编程
核心是“过程”二字,过程指的是做事的步骤,也就是说先做什么,在做什么,然后做什么…
基于该思想写程序就好比设计一条条的流水线
优点:
可以把复杂的问题流程化,进而简单化
缺点:
牵一发而动全身,拓展性差
8、列表生成式
l=[i**2 for i in range(5) if i > 2]
print(l)
9、字典生成式
dict1 = {k: v for k, v in zip(s, range(len(s)+1)) if v < 6}
print(dict1)
10、集合生成式
res={i for i in range(5)}
print(res)
11、生成器表达式
nums=(i for i in range(200000))
res=sum(nums) # sum函数生成两数和,删掉原来的两个数
print(res) # 19999900000