python基础9 (迭代器、生成器)
1、可迭代对象
迭代:将某个数据集内的数据“一个挨着一个的取出来” 可迭代协议:可以被迭代要满足的要求,即内部含有__iter__()方法 可迭代的类型:字符串、列表、元组、字典、集合
特点:惰性运算 #我们可以用dir()来查看是否还有__iter__()方法 have_iter = '__iter__' in dir([1,2]) #如果有,则have_iter = True
2、迭代器、__next__()
当我们调用可迭代对象的__iter__方法的时候,会返回一个例如list_iterator的类型,就是一个迭代器 迭代器协议:必须拥有__iter__方法和__next__方法 l = [1,2,3,4] l_iter = l.__iter()__ #获得了迭代器 ret1 = l_iter.__next__() #获得第一个元素 ret2 = l_iter.__next__() #获得第二个元素 for循环就是这样进行迭代的
3、生成器、yield
Python中提供的生成器: 1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。 2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表 #yield yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行。通过调用__next__()和send()可以使生成器继续执行到下一个yield,不同的是send会传一个值给上一个yield
4、生成器函数
#例子:生成500万个hsr def generate_hsr(): for i in range(5000000): yield 'hsr' g = generate_hsr() for i in g: print(i)
5、send
#send获取下一个值,传值给上一个yield #第一次使用生成器用next 最后一个yield不能接受传值 def generator(): print(123) content = yield 1 print(content) yield 2 g = generator() ret1 = g.__next__() #ret1 =1 ret2 = g.send('hsr') #输出hsr 并 ret2 = 2
6、计算移动平均值
def avg_generator(): sum = 0 count = 0 avg = 0 while 1: num = yield avg count += 1 sum += num avg = sum / count g = avg_generator() r = g.__next__() print(r) for i in range(5): ret = g.send(int(input())) print(ret)
6、预激协程的装饰器
# 用装饰器进行一次next,后面就可以直接使用 def init(func): def inner(*args,**kwargs): g = func(*args,**kwargs) g.__next__() return g return inner @init def avg_generator(): sum = 0 avg = 0 count = 0 while 1: num = yield avg count += 1 sum += num avg = sum / count g = avg_generator() print(g.send(10)) print(g.send(15)) print(g.send(20))
7、yield from
#可以从容器中直接一个一个返回值 def generator(): l = [1,2,3,4,5] yield from l g = generator() for i in g: print(i) #结果 1 2 3 4 5
9、列表推导式
#形式 #[满足条件的元素 for 元素 in 可迭代对象 if 条件] li = [i for i in range(31) if i % 3 == 0] #得到30内可以被3整除的数的列表 #嵌套 li2 = [[1,2,3,4,5],[6,7,8,9,10]] ret = [i for ls in li2 for i in ls if i %2 == 0] #得到嵌套列表中可以被2整除的数的列表
10、生成器表达式
#和列表推导式类似,将[]换成() #不同的是生成器表达式得到的是一个迭代器,而不是全部的数据 g = (i for i in range(10)) print(g) #会得到类似<generator object generator ...> #可以使用for循环获取值 for i in g: print(i)
11、字典推导式
#以将键值对换为例(注意值要是不可迭代对象) dic = {'a':10,'b':20} dic_frequency = {dic[k]:k for k in dic}
12、集合推导式
#和列表推导式类似,将[]换成{},结果会去重 squared = { x**2 for i in [1,-1,2]} #结果 squared = {1,4}