四、迭代器、生成器、三元表达式、列表生成式
目录
一、迭代器
二、生成器
三、三元表达式
四、列表生成式return
五、字典生成式
一、迭代器
1.1 什么是迭代器
#迭代的工具 #什么是迭代? #迭代是一个重复的过程,每一次重复都是基于上一次结果而进行的 #错误案例: #单纯的重复不是迭代 while True: print ('===>') #正确案例: count=0 while count >10: #重复的过程 count +=1 #每一次重复都是基于上一次的结果而进行的 print (count)
1.2 为什么要用迭代器
#找到一种可以不依赖索引的迭代取值方式
1.3 怎么用迭代器
名词介绍: #1.可迭代对象iterable: #在python中,但凡内置有__iter__方法对象,都是可迭代的对象 #2.迭代器对象iterator: #执行可迭代对象下__iter__方法得到的返回值就是一个迭代器对象 #3.迭代器对象内置: #__next__方法 #__iter__方法,执行该方法得到仍然是迭代器本身 #由第3点可知迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象 使用迭代器原理: #1.使用可迭代对象(如,列表,字典等等)的__inter__方法,返回值为迭代器对象iterator #2.使用迭代器对象里的__next__方法(或next(迭代器对象))取到迭代器里的一个值 #3.重复步骤2,直到遇到StopIteration报错提示,显示值已取完 #迭代器使用例子: names=['唐三', '小舞', '唐昊', '胖子', '戴沐白'] iterator_obj=names.__iter__() #可迭代对象.__iter__()返回值为迭代器对象 iterator_obj.__next__() iterator_obj.__next__() iterator_obj.__next__() iterator_obj.__next__() iterator_obj.__next__() iterator_obj.__next__() #for循环的底层运行机制:for循环可以称之为迭代器循环 #1.先调用in后那个对象的__iter__方法,得到该对象的迭代器对象 #2.执行迭代器对象的__next__方法,将得到的返回值赋值给In前面的变量名,然后执行一次循环体代码 #3.循环往复,直到取干净迭代器内所有的值,自动捕捉异常结束循环 #例子: dic = {'name':'唐三','level':29,'sex':'男'} for k in dic: #dic.__iter__()==>obj.__next()==>k print (k)
1.4 总结迭代器
#优点: #1.提供一种不依赖与索引的迭代取值方式===》应用于for循环 #2.节省内存 #缺点: #1.只能往后取,不能往前取,是一次性的,值取干净后无法再次取值,除非重新得到新的迭代器对象,不如按照索引取值的方式灵活 #2.值没取完,永远无法预测迭代器的长度
1.5 Python2.x与Python3.x中的range()
#Python2.x中的range()返回的结果是列表 #Python3.x中range()返回的结果是可迭代对象
二、生成器
2.1 什么是生成器
#在函数内但凡有yield关键字,在调用函数就不会执行函数体代码,得到的返回值就是一个生成器对象 #强调:生成器本质就是迭代器 #next(g)过程: #会触发生成器g所对应的函数的执行,直到遇到yield才停下来,然后把yield后的返回值当做本次next操作的结果
2.2 为何要用生成器
#为了掌握一种自定义迭代器的方式
2.3 总结yield:
#1.yield提供一种自定义迭代器的方式 #2.与return对比,都能返回值,都能返回多个值,都没有类型限制 #3.不同的是:而return只能返回一次值,而yield可以返回多次值(yield可以帮我们保存函数的执行状态) #例子: def func(): print ('first') yield 1 #暂停 print ('second') yield 2 #第二次暂停位置 print ('third') g=func() #返回值为生成器对象 print (next(g)) print (next(g)) print (next(g)) #报错,因为第三次只有函数体没有yield,for循环可以规避这个问题for i in fun():print (i)
2.4 例子: 实现range()功能
def myrange(start,end,step=1): while start < end: yield start start += step g=myrange(1,10,2) for i in g: print (i)
2.5 yield 的表达式形式应用
def people(name): print ('[%s]去过的城市'%name) travel_city=[] while True: city=yield travel_city #yield表达式应用 print ('[%s]去了%s'%(name,city)) travel_city.append(city) g=people('唐三') next(g) #第一次为空列表,也可使用g.send(None) g.send('广州') g.send('青海') print ('都去过的城市列表:',g.send('西双版纳'))
· 2.6 生成器表达式
g= (i for i in range(10000000000000000000000000000000000)) #返回生成器 print (type(g),g) print (next(g)) #需求:计算文件中最长的行长度,打印长度与内容 with open('file1.txt','r',encoding='utf-8') as f: g=((len(line),line) for line in f) print (max(g))
三、三元表达式
#普通做法 def max2(x,y): if x>y: return x else: return y res=max2(1,3) #三元表达式 x=10 y=30 res=x if x>x else y #三元表达式 print (res)
四、列表生成式
4.1 定义
#普通做法 l=[] for i in range(10): l.append('egg%s'%i) print (l) #列表生成式 l=['egg%s'%i for i in range(10)] print (l)
4.2 举例
#需求:将名字前面加上序号 names=['路飞','索隆','娜美','乔巴','香吉士'] names=[str(index+1)+name for index,name in enumerate(names)] print (names) #需求:将带有.jpg的名字过滤掉 names=['路飞.jpg','索隆.pdf','娜美.jpg','乔巴.pdf','香吉士.jpg'] names=[name for name in names if not name.endswith('.jpg')] print (names)
五、字典生成式
#字典生成式1 d={i:i for i in range(10) if i>0} print (d)
userinfo=[('路飞','15亿'),('索隆','3亿2千万'),('乔巴','100')] user_dic={i[0]:i[1] for i in userinfo} print (user_dic)