迭代器
迭代器iterator
同时有__next__(),__iter__()方法的数据类型可以被称为迭代器
可迭代iterable
有__iter__()方法的数据类型可以被迭代
可迭代的数据类型(iterable):list,dic,str,set,tuple,enumerate,f(文件句柄),range()
迭代器的好处:节省内存空间,从容器类型中一个一个取值,会把所有值都取到
print(dir([].__iter__()))#dir查看方法
range(10)#只是创建了一个迭代器,并没有创建数据
生成器
生成器:自己写的迭代器
1.生成器表达式
列表推导式:返回一个列表,一下返回一个列表,占用内存较大
list1 =[i*i for i in range(10)]
生成器表达式:返回一个生成器(迭代器)-->几乎不占用内存
gen = (i*i for i in range(10))#此时并没有执行 for i in gen: #遍历迭代器 print(i)
各种推导式
# 1.加过滤条件的推导式 gen = (i for i in range(10) if i%2==0) for i in gen: print(i) #2.嵌套列表过滤,查找names列表中含有a字符的元素 names=[['aqa','yhaga'],['wed','uhsy']] ret = (i for name in names for i in name if 'a' in i) for i in ret: print(i) #字典推导式,key,value对调 dic = {1:'j',2:'c'} dic_new = {dic[i]:i for i in dic} print(dic_new)
2.生成器函数
只要函数中含有yield关键字就是生成器函数,yield只能在函数内部使用,且不能与return同时出现
#例子1:制造两百万个jcc def jcc(): for i in range(2000000): yield 'jcc %d'%i gen = jcc() #生成器(迭代器) for i in gen: print(i) #for循环遍历迭代器。边取值边打印,不占内存 #例子2:监听文件的输入 #不用函数 with open('d:jcc.txt',encoding='utf-8') as f: line = f.readline() while 1: if line: print(line) #封装成一个函数 def fun(filename): with open(filename, encoding='utf-8') as f: while 1: line = f.readline() if line.strip(): yield line.strip() #返回line再做其他的处理 line = fun('d:jcc.txt') for i in line: print(i)
send
获取下一个yield的同时,向上一个yield传递一个值,使用send之前必须要先调用一次next函数
def generator(): print(1) content = yield 'jcc'#content接收send传过来的值 print(content) print(2) yield 2 ret = generator()#返回一个迭代器,此时并不执行函数 res = ret.__next__()#执行函数,返回yield后面的值 ret.send('hello') print(res)
yield from
def gen(): a='abc' b = '1234' yield from a #相当于下面的两行 # for i in a: # yield a yield from b # for i in b: # yield b g = gen() for i in g: print(i)