标签:bsp python 管理器 class 本质 迭代器 对象 结果 break
迭代器
迭代器只不过是一个实现了迭代器协议的容器对象。它基于以下两个方法。
__ next __
:返回容器的下一个元素。
__ iter __
:返回迭代器本身。
实际上,迭代器表现了程序底层的概念和特性,在程序中,你可以不必使用迭代器,但是理解迭代器,却是对生成器这样一个常用特性理解很有帮助。
学习迭代器,我基本上通过2个例子来理解迭代器的特性。(PS:我发现我之前记得笔记不是很详细,所以这一篇记录详细一些……不然我有时候一些点我自己看的时候都要想一下,吐血,果然没什么灵性……)
好了,上代码:
a = iter([11,22,33])
print(next(a))
print(next(a))
print(next(a))
-------------------------
11
22
33
[Finished in 0.2s]
这里,我创建了一个非常简陋的迭代器,使用iter()函数,这个函数在上述的代码中接收了一个列表作为参数,并赋值给a这个变量。
那么此时,a就是一个迭代器了。当然,此时创建的这个a的迭代器非常的简陋,就好比我要造飞机,结果你用纸给我叠了一个。不过飞机的特性还是有的,可以算是飞机了,只不过是纸飞机。
迭代器使用:通过函数next()来使用,next()函数参数接收一个迭代器,并在每一次执行的时候,依次调取迭代器中的值,并返回出来。
简单理解:next()函数呢,就好比游戏登录器,游戏就好比迭代器,没有登录器你玩不了游戏,所以,没next()这玩意你用不了迭代器,想用迭代器,你需要用next()这个方法调,next()这个方法有一个特点,从头开始调,每次调一个。
那么,为什么说我们用iter()创建的迭代器是纸飞机呢?
看代码思考2个问题:
1,每次调用是进行依次调用的,上述代码调用的刚好是个列表,如果,调用列表中最后一个值之后,继续调用,会怎么样呢?
a = iter([11,22,33]) print(next(a)) print(next(a)) print(next(a)) print(next(a)) ------------------------- StopIteration [Finished in 0.2s with exit code 1]
可以看到,迭代器中只有3个值,而我调用了4次,所以在第四次调用的时候,返回了一个StopIteration异常。这是好事,异常代表着迭代的完结,我们可以利用异常做点事情。
2,为什么说纸飞机呢,这个迭代器有一个非常不好的点,那就是迭代的次数并非我们想要的,如果我们想迭代100次,总不至于写一个有100个元素的列表吧?当然,你可以说我可以用range()来解决这个问题呀。
a = iter(range(4)) print(next(a)) print(next(a)) print(next(a)) print(next(a)) ------------------------------- 0 1 2 3 [Finished in 0.2s]
可是,实际上,并没有解决触发异常的问题。并且每一次的迭代,都需要next()来手工进行,那么,我们来做一个真正的迭代器。
class CountDown(): def __init__(self,step): self.step = step def __next__(self): if self.step <= 0: raise StopIteration self.step = self.step - 1 return self.step def __iter__(self): return self ff = CountDown(5) for i in ff: print(i) ------------------------------------- 4 3 2 1 0 [Finished in 0.2s]
__ next __
:返回容器的下一个元素。
__ iter __
:返回迭代器本身。
这个类就非常明确了,接收迭代次数,并且每次迭代减1,触发异常停止迭代。实际上,迭代只是一种概念,迭代器则提供了一种专门的方法,并非在python程序中唯一的迭代动作!
生成器
生成器是一种优雅的方法,他可以让编写返回元素序列的函数代码变得简单,高效。
实际上,我们常用的方法:range()
for i in range(10): print(i)
也是生成了一个列表来供我们遍历,在python3中,本质也是生成器。
当然,我们也可以自己写一个列表生成器,不使用range()
def Maker(num): a = 0 while True: b = a a = a + 1 num = num - 1 yield b if num <= 0: break ff = Maker(10) a = [i for i in Maker(10)] b = [x for x in range(10)] print(a) print(b) -------------------------------------------- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [Finished in 0.2s]
看,我们自己写了一个生成器方法Maker(),这个方法接收一个参数,来表示生成列表数量,与range()函数的方法是一样的。(起码在调用看来是的)
代码中的:yield语句,表示暂停生成器,返回结果。是不是有点像return?可以想一想,是有区别的,一个是暂停,返回后继续执行后面的代码,return返回后就不在执行啦。
实际上,生成器可以执行复杂的生成过程,不过具体还是要看你要实现什么需求。
Python学习日记(5)简单了解迭代器、生成器、装饰器、上下文管理器
标签:bsp python 管理器 class 本质 迭代器 对象 结果 break
原文地址:https://www.cnblogs.com/shsm/p/9342552.html