python——迭代器、列表解析、三元表达式
一.迭代器
1.迭代器协议和迭代器对象
(1)迭代器协议是指:
对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stoplteration异常,以终止迭代
(2)可迭代对象:
实现了迭代器协议的对象(如何实现:对象内部定义一个_iter_()方法)
(3)协议:
是一种约束,可迭代对象实现了迭代器协议,python的内部工具(如:for循环,sum,min函数等)使用迭代器协议访问对象
2.标准的迭代器接口有两个方法:
_iter_:返回self,以便在应该使用迭代器的地方使用迭代器,例如:for循环 _next_:返回下一个可用的元素,如果没有元素了抛出StopIteration异常
3.简单来说:可迭代器
就是创建一个对象的类是否定义了_iter_()方法,如果定义了,那么这个对象就是可迭代对象
4.可迭代对象和迭代器的区别:
可迭代对象有_iter_方法,每次都要实例化一个新的迭代器
迭代器要实现_next_和_iter_两个方法,_next_用于获取下一个元素,_iter_用于迭代器本身,所以迭代器可以迭代,但是可迭代对象不是迭代器
注:可迭代对象一定不能是自身的迭代器
案例:
list=[1,2,3,4,5] a_list=list.__iter__() #遵循迭代器协议,生成可迭代器 print(a_list.__next__()) #打印结果为1 print(a_list.__next__()) #打印结果为2 print(a_list.__next__()) #打印结果为3 print(a_list.__next__()) #打印结果为4 print(a_list.__next__()) #打印结果为5 print(a_list.__next__()) #报错,超出了范围 注:超出了list的范围会报错
二.生成器
1.理解生成器
可以理解为是一种数据类型,这种数据类型可以自动实现迭代器协议(其它的数据类型需要调用自己的内置的_iter_方法),所以生成器就是可迭代对象
2.生成器分类
(1)生成器函数:
常用函数定义,但是使用yield语句而不是return语句返回结果,yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行
(2)生成器表达式:
可以理解为列表推导的惰性版本,它的好处就是延时计算,不会直接构成列表,简单来说就是一次返回一个结果,不是一次生成所有结果
3.生成器的优点:
使用生成器对延迟操作提供了支持。延迟操作是指需要的时候才产生结果,而不是立即产生结果,这就是生成器的好处
4.yield
概述:
yield关键字的核心用法,即逐个生成。在这里获取了两个生成器产生的值,即0和1。分别由next函数和send()函数获得
常用的三种方法:
生成器对象._next_() next(生成器对象) 生成器对象.send("从参数")
案例:
#使用yield特征 def fun(): a = [1, 2, 3, 4] #定义一个a的列表 print("这是方法") yield a[2] #这里我是通过下标来取得 text=fun() print(text) print(text.__next__()) #输出结果为: #<generator object fun at 0x0000018795A7A200> #这是方法 #3
5.三元表达式
语法:
真值结果 if 判断语法 else 假值结果
#案例:
name="lisi" name_list="名字正确" if name=="lisi" else "没有这个人" #三元表达式,如果条件成立的情况下,这执行if前面的内容,如果条件不成立的,则执行else下的内容 print(name_list) #这里结果为:“名字正确”
6.列表解析
案例:
#通过二元表达式来写 list=["第%s次" %i for i in range(10)]#这是二元表达式 print(list) #结果为:['第0次', '第1次', '第2次', '第3次', '第4次', '第5次', '第6次', '第7次', '第8次', '第9次'] #通过三元表达式(第三元后面需要添加i>5的条件) list_s=["第%s次" %i for i in range(10) if i>5]#这是三元表达式,在第三元上添加i>5的条件 print(list_s) #结果为:['第6次', '第7次', '第8次', '第9次']
注:可以有二元表达式,没有四元表达式
补充:
把列表解析的[]换成()得到的就是生成器表达式
列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节约内存