1、迭代器协议
- 协议:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么引起一个Stoplteration异常,以终止迭代(只能往后不能往前)
- 可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)
- 协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。
2、for循环机制
- 本质:循环所有对象,全部使用迭代器协议
- for循环:先调用对象的__iter__方法将其转换成一个迭代器,然后使用迭代器协议实现循环访问。
1 # for i in l: # 相当于:i_l = l.__iter__() ; i_l.__next__() 2 l = [0,1] 3 l_iter = l.__iter__() #生成可迭代对象,遵循迭代器协议 4 print(l_iter.__next__()) 5 print(l_iter.__next__()) 6 7 输出: 8 0 9 1
1 #使用while循环模拟for循环所作的事 2 l = [1,2,3] 3 l_test = l.__iter__() 4 while True: 5 try: 6 print(l_test.__next__()) 7 except StopIteration: 8 print('迭代结束。') 9 break 10 11 输出: 12 1 13 2 14 3 15 迭代结束。
3、列表生成式:把要生成的元素放在前面,后面跟 for 循环,把list列表创建出来,后面可加 if 判断或者继续再使用 for
1 #计算列表[1x1, 2x2, 3x3, ..., 10x10]的结果,并能被2整除的数。 2 3 print(list(x * x for x in range(1,11) if x%2==0)) 4 5 输出: 6 [4, 16, 36, 64, 100]
1 #使用for循环来求值 2 3 l = [] 4 for i in range(1,11): 5 if i % 2 == 0: 6 l.append(i*i) 7 print(l)
4、生成器
- 一种数据类型,能自动实现迭代器协议(其它需调用自身内置的__iter__方法),所以生成器就是可迭代对象。
- 两种形式:
- 1、生成器函数:函数使用yield语句而不是return语句返回,一次返回一个结果,中间挂起函数状态,以便下次从离开的地方执行(yield可返回多次值)
1 def test(): 2 yield 1 3 yield 2 4 f = test() 5 print(f) 6 print(f.__next__()) #可直接使用next方法 7 print(f.__next__()) 8 9 输出: 10 <generator object test at 0x000000D2D88590C0> #生成迭代器 11 1 12 2
2、生成器表达式:类似类表推导,在列表解析的里面用上三元表达式。(将原本生成的列表赋予到一个值中,再从中取值,不直接生成一个列表,减少内存)
1 #将下文列表解析的 [] 换成(),就是生成表达式。 2 renwu_list = ('任务%s' %i for i in range(10)) 3 print(renwu_list.__next__()) 4 print(renwu_list.__next__()) 5 6 输出: 7 任务0 8 任务1
1 #列表解析 2 list = ['任务%s' %i for i in range(10)] 3 print(list) 4 # list = [] 5 # for i in range(10): 6 # list.append('任务%s' %i) 7 # print(list) 8 9 输出: 10 ['任务0', '任务1', '任务2', '任务3', '任务4', '任务5', '任务6', '任务7', '任务8', '任务9']
- 三元表达式
1 name = 'jack' 2 res = 'yes' if name == 'jack' else 'no' #if为True时返回yes 3 print(res) 4 5 输出: 6 ye
- 1、生成器函数:函数使用yield语句而不是return语句返回,一次返回一个结果,中间挂起函数状态,以便下次从离开的地方执行(yield可返回多次值)
5、总结
- 语法与函数类似;自动生成迭代器协议;状态挂起。
- 优点:1、延迟计算,一次返回一个结果。2、有效提高代码可读性
- 注意:生成器只能遍历一遍