03 - 迭代器与生成器
Posted liulyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了03 - 迭代器与生成器相关的知识,希望对你有一定的参考价值。
迭代器与生成器
迭代器
可迭代对象
字符串、列表、元组、字典、集合 都可以被for循环,说明他们 都是可迭代对象 。
print([1,2].__iter__()) #结果 <list_iterator object at 0x1024784a8>
迭代器
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
字符串,列表或元组对象都可用于创建迭代器,文件本身就是迭代器对象。
迭代器有两个基本的方法
迭代器 :必须拥有__iter__方法和__next__方法。
iter(obj) 和 next(obj) <<====>>obj.__iter__ 和 obj.__next__
obj为可迭代对象,通过__iter__()变成迭代器,迭代器对象可以通过__next__()取值。
生成器 ⊆ 迭代器 ⊆ 迭代对象
优点: 1、提供一种不依赖与索引的迭代取值方式==>>应用于for循环
2、节省内存
from collections import Iterable,Iterator # Iterable可迭代,Iterator迭代器 isinstance([], Iterable) #ture isinstance(‘abc‘, Iterable) #ture #------------------------------------------------ isinstance((x for x in range(10)), Iterator) #true isinstance([], Iterator) #false print(isinstance([].__iter__(), Iterator)) #true
for循环机制
1、先调用in后那个对象的__iter__方法,得到该对象的迭代器对象
2、执行迭代器对象的__next__方法,将得到的返回值赋值in前面的变量名,然后执行一次循环体代码
3、循环往复,直到取干净迭代器内所有的值,自动捕捉异常结束循环
类做迭代器
__iter__()方法返回一个特殊的迭代器对象, 这个迭代器对象实现了__next__()
方法并通过StopIteration异常标识迭代的完成。
class Test(object): def __iter__(self): self.a = 1 return self def __next__(self): b = self.a self.a +=1 return b test = Test() it = test.__iter__() print(it.__next__()) #1 print(it.__next__()) #2 print(it.__next__()) #3 print(it.__next__()) #4
生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值,并在下一次执行
next() 方法时从当前位置继续运行。
简单生成器的创建
a = ( x*2 for x in range(5)) print(type(a)) #<class ‘generator‘>
用yield创建生成器
#生成器,主要生成特定的数,每调用一次生成一个数,不会占用太大空间 def creatNum(num): # 生成器函数 - 斐波那契 print("-----start------") a,b = 0,1 for i in range(num): #相当于return yield b #函数加yield就变成生成器,无法正常调用,返回的是一个实例对象的值 a,b = b,a+b print(" ------end-------") a = creatNum(10) #a是一个迭代器,由生成器返回生成 while True: try: print(next(a),end=‘ ‘) except Exception as e: print(e) break #结果 -----start------ 1 1 2 3 5 8 13 21 34 55 ------end-------
send(None)带参数
def test(): i = 0 while i<5: temp = yield i #每次yield返回值时会产生断点,下次调用会从断点出读取。 print(temp) i+=1 t = test() print(type(t)) print(t.__next__()) #0 print(t.__next__()) #None,1 t.send(‘ni‘) #ni # send()和__next__等价,send()可以传递参数 # t,send(None)开头用None
yield案例
# The most glorious thing is labor. def labor(): print("The most glorious thing is",end=‘ ‘) a = yield 5 print(a) b = yield 1 print("Traceback (most recent call last):") l = labor() print(type(l)) m = l.__next__() #获取了yield 5 的参数值 5 n = l.send("labor") #获取了yield 1 的参数值 1 print("Labor Day date:%d月%d号"%(m,n)) #结果: <class ‘generator‘> The most glorious thing is labor Labor Day date:5月1号
enumerate(迭代器生成元组)
#生成一个11,20的列表 ls = [a+1 for a in range(10,20)] #列表生成器[10,20) print(ls) for i in enumerate(ls): #将迭代器生成元组 print(i) #(0, 11) #(1, 12) #(2, 13) #... #(9, 20)
range生成器
#生成偶数列表 a = [i for i in range(10) if i%2==0] #range(x),默认[0,x) print(a) #[0, 2, 4, 6, 8] # #生成5个0 b =[0 for i in range(5)] print(b) #[0, 0, 0, 0, 0] # #生成 1,1,2,2,3,3 c = [i for i in range(1,4) for j in range(2)]#第一个for显示数字,第二个for次数 print(c) #[1, 1, 2, 2, 3, 3] d = [(i,j) for i in range(3) for j in range(2)]#相当于for循环的嵌套 print(d) #[(0,0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
以上是关于03 - 迭代器与生成器的主要内容,如果未能解决你的问题,请参考以下文章