迭代器
可迭代协议:只要含有__iter__方法的都是可迭代的,只要是能被for循环的数据类型 就一定拥有__iter__方法
迭代器协议 :内部含有__next__和__iter__方法的就是迭代器
迭代器的好处:
从容器类型中一个一个的取值,会把所有的值都取到
节省内存空间,迭代器并不会在内存中再占用一大块内存,而是随着循环 每次生成一个,每次next每次给我一个
注意:
__next__()方法当取完时候会报错。print(dir([])) #告诉我列表拥有的所有方法,其他的只要改想知道的类型就可以了
生成器
生成器 ----也是一种迭代器,即含有__next__和__iter__方法
生成器函数
#只要含有yield关键字的函数都是生成器函数# yield不能和return共用且需要写在函数内def generator(): print(1) yield 'a'# #生成器函数 : 执行之后会得到一个生成器作为返回值ret = generator() #得到一个内存地址print(ret) #,通过next取值,一个yield返回一个值print(ret.__next__()) #打印 1 a
生成器函数进阶:
def generator(): print('123456789*') contend = yield 1 print('==========',contend) print('*987654321') yieldg = generator()print(g.__next__())#send的效果和next一样,都是往下执行,只是在获取下一个值的时候,给上一yield的位置传递一个数据#使用send的注意事项 # 第一次使用生成器的时候 是用next获取下一个值 # 最后一个yield不能接受外部的值g.send('hello')# print(g.__next__()) 思考:打印的是什么?# 获取移动平均值# 10 20 30 10# 10 15 20 17.5def average(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num # 10 count += 1 # 1 avg = sum/countavg_g = average()avg_g.__next__()avg1 = avg_g.send(10)avg1 = avg_g.send(20)print(avg1)'''重点思考代码的执行过程?'''#预激生成器的装饰器def init(func): #装饰器 def inner(*args,**kwargs): g = func(*args,**kwargs) #g = average() g.__next__() return g return inner@initdef average(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num # 10 count += 1 # 1 avg = sum/countavg_g = average() #===> innerret = avg_g.send(10)print(ret)ret = avg_g.send(20)print(ret)'''重点思考执行过程?然后能写下来'''
生成器表达式
'''把列表解析的[]换成()得到的就是生成器表达式'''#列表解析li = [i*2 for i in range(5)] #内存占用大,机器容易卡死print(li) #li = [0, 2, 4, 6, 8]print(type(li)) ##生成器表达式li = (i*2 for i in range(5)) #几乎不占内存print(li) # at 0x000002BC67B8D930>print(type(li)) #
各种推导式:
#列表推导式multiples = [i for i in range(30) if i % 3 is 0] #30以内所有能被3整除的数# def squared(x):# return x*xmultiples = [i*i for i in range(30) if i % 3 is 0] #30以内所有能被3整除的数的平方print(multiples)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]) # 注意遍历顺序,这是实现的关键#字典推导式mcase = { 'a': 10, 'b': 34} #将一个字典的key和value对调mcase_frequency = {mcase[k]: k for k in mcase}print(mcase_frequency)#集合推导式squared = {x**2 for x in [1, -1, 2]}print(squared)# Output: set([1, 4])