迭代器
iterable
l1=[1,1,1,1,1,1,1,1,1]#列表 l2=l1.__iter__() #迭代器 print("__iter__" in dir(l1))#查看是否是可迭代对象的方法 print("__iter__" in dir(l2)) #上面列表和迭代器这两个都是可以迭代的对象. print("__next__" in dir(l1))#不是迭代器 print("__next__" in dir(l2))#是迭代器 print(l1.__next__())报错 print(l2.__next__())迭代器的三个意义
迭代器的意义
因为是逐行循环的所以节省内存,
有惰性机制
迭代器不能反复,从头向下执行,执行到哪里就会是哪里,往后不会从头开始执行
try异常处理
try:
要输入的异常错误代码
except:
break
生成器
本质其实其迭代器,其实是用代码编写的迭代器
三种方式
1,可以用生成器函数
关键字
yield
yield和return的却别
1.返回调用的值并停留在当前的位置.
def func(): print(11,1,1,1,1,1) yield print(func())#简单的生成器 <generator object func at 0x0000020C2D1D8780>是其结果
2,可以用各种推导公式
3.可以用数据转换
send和next的用法一样
__send__
给上一个yeild返回一个值,不能用在最后一个和第一个.
生成器的三种方法
1.生成器函数
yield函数可以生成一个生成器
2.各种推导公式
l2=[i for i in rang (111)]
l2=[i for i in range(111) if ]
3.数据转化的生成器
转化为列表元组,
list()tuple()
迭代器、生成器
1、迭代器
可迭代对象:它的方法含有__iter__,可被for循环的对象。
for循环 str list tuple dict set 文件句柄
①可迭代对象(iterable)与迭代器(iterator)的关系:
可迭代对象---->迭代器:可迭代对象.__iter__() 迭代器遵循迭代器协议。
迭代器取值:s.__next__() 每次取一个值。
可迭代对象和迭代器区别:只含有__iter__方法的数据是可迭代对象,含有__iter__方法并且含有__next__方法的数据是迭代器。
②可迭代对象判断方法:
方法一:dir(被测试对象),print('__iter__' in dir(s)),如果它的方法含有__iter__,那这个对象就叫做可迭代对象。遵循可迭代协议。
方法二:测试它是迭代器还是可迭代对象。
1
2
3
4
5
6
|
l = [ 1 , 2 , 3 , 4 ] l_iter = l.__iter__() from collections import Iterable #可迭代对象 from collections import Iterator #迭代器 print ( isinstance (l,Iterable)) print ( isinstance (l,Iterator)) |
③迭代器的特点。
Ⅰ 节省内存
Ⅱ迭代器惰性机制
Ⅲ迭代器不能反复,一直向下执行。不可逆。
④for循环的内部机制。
for循环的内部含有__iter__方法,它会将可迭代对象先转化成迭代器,然后再调用__next__方法取值,它有异常处理的方法。
⑤可迭代对象:str list tuple dict set
迭代器:文件句柄
2、生成器
生成器的本质就是迭代器,生成器是自己用Python代码写的迭代器。
含有yield就是生成器。
(1)用生成器函数写生成器。
1
2
3
4
5
6
|
#生成器函数 def gener(): print ( 111 ) yield 222 g = gener() print (g) |
.__next__()遇到yield停住,可以再一次.__next__()来继续执行,如果.__next__()找不到下一个yield就会报错。
send和.__next__功能一样,但是send会给上一个yield整体发送一个值,所以最后一个yield永远得不到send发送的值,获取第一个值的时候不能用send只能用next
注:
return和yield区别:
return返回给调用者值,并结束此函数。
yield返回给调用者值,并将指针停留在当前位置。
(2)推导式/生成器表达式构建迭代器。
①列表推导式
Ⅰ 列表推导式(循环模式):[变量(加工后的数据)for 变量i in 可迭代的数据类型]
l2 = [ 'python%s期' % i for i in range ( 1 , 11 )] print (l2) |
Ⅱ列表推导式(筛选模式):[变量(加工后的数据)for 变量i in 可迭代的数据类型 if 条件]
l3 = [i for i in range ( 31 ) if i % 3 = = 0 ] #30以内能被3整除的数 print (l3) |
#找到嵌套列表中名字含有两个‘e’的所有名字 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] print([name for lst in names for name in lst if name.count('e') >= 2])
列表推导式比较直观,占内存。生成器表达式(for循环)不容易看出内容,但是省内存。
②字典推导式
#将一个字典的key和value对调 mcase = { 'a' : 10 , 'b' : 34 } mcase_frequency = {mcase[k]: k for k in mcase} print (mcase_frequency) |
#合并大小写对应的value值,将k统一成小写 mcase = { 'a' : 10 , 'b' : 34 , 'A' : 7 , 'Z' : 3 } mcase_frequency = {k.lower(): mcase.get(k.lower(), 0 ) + mcase.get(k.upper(), 0 ) for k in mcase.keys()} print (mcase_frequency) |
③集合推导式
#计算列表中每个值的平方,自带去重功能 squared = {x * * 2 for x in [ 1 , - 1 , 2 ]} print (squared) # Output: set([1, 4]) |
(3)可以通过数据转化
list()和tuple()将生成器对象转化,一般不需要。