1、迭代器协议:
1、迭代器协议是指:对象必须提供一个 __next__() 方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代(只能往后走不能往前退)
2、可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义了一个__iter__()方法)
3、协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。
注意:
iter.ls__next__() #__next__() ---->next() __next__() 是迭代器内置函数,而next() 是python内置函数,两者效果相同
字符串、列表、元组、字典、集合等 都不是可迭代对象,但是能够被for循环,
for循环其实就是先把它们转化为可迭代对象( li.__iter__()或者iter(li) ),然后进行__next__()方法一个个取出
>>> a = iter([1,2,3,4,5]) >>> a <list_iterator object at 0x101402630> >>> a.__next__() 1 >>> a.__next__() 2 >>> a.__next__() 3 >>> a.__next__() 4 >>> a.__next__() 5 >>> a.__next__() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
>>>for i in range(a):
print(i)
>>>1
>>>2
>>>3
>>>4
>>>5
#当遇到StopIteration时停止迭代
2、生成器
一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器;
li = ['鸡蛋%s'%i for i in range(10)] #生成器表达式 print(li)
在函数中只能有一个return 返回,但是却可以有多个yield 生成器返回
def func(): print('1111') print('2222') yield 1 print('aaa') yield ('bbb') yield "success" print('ccc') yield "enter" fx = func() print(fx.__next__()) # 第一次使用__next__()打印到yield 1 的位置, 1111 2222 1 print(fx.__next__()) # 第二次使用__next__()打印到yield 'bbb' 的位置, aaa bbb print(fx.__next__()) #success print(fx.__next__()) #ccc enter
有效利用yield生成器这个工具可以有效地节约系统资源,避免不必要的内存占用。
yield生成器每次生出一个值占用较少的内存,就像餐馆里上餐是做好一个菜上一个菜而不是把全部菜都做好了之后再上菜
"""yield i+1 每次向内存中放入一个值,占用较少的内存""" def func1(): for i in range(100): yield i+1 f1 = func1() print('来了第%s个人'%(f1.__next__())) #来了第1个人 print('来了第%s个人'%(f1.__next__())) #来了第2个人 print('来了第%s个人'%(f1.__next__())) #来了第3个人 """return ret 是将生成的[1,2,3,4...100]数组直接放在内存中,耗费较多内存""" def func2(): ret = [] for i in range(100): ret.append(i+1) return ret f2 = func2() print("来了第%s个人"%(f2[1])) #来了第2个人
补充知识点:
三元表达式:
"""三元表达式""" name = 'jt' res = 'xiong' if name == 'jt' else 'zhang' print(res)
列表解析:
egg_list = [] for i in range(10): egg_list.append('鸡蛋%s'%i) print(egg_list)
"""列表解析""" li = ['鸡蛋%s'%i for i in range(10)] print(li) #打印出来的结果都是: ['鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9']
"""列表解析与三元表达式结合"""
li = ['鸡蛋%s'%i for i in range(10) if i>5]
print(li)
#打印出来的结果都是:
['鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9']
#注意:
#li = ['鸡蛋%s'%i for i in range(10) if i>5 else i<2] #没有4元表达式 这种写法错误