一、迭代器
迭代:迭代是一个重复的过程,每次重复都是基于上一次重复的结果!而每次重复就是一次迭代!迭代是Python最为强大的功能之一,是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完成后结束。此外,迭代顺序只能往前不能回退。
迭代对象:能够进行迭代取值的对象,如字符串,列表,元组,文件,迭代器等
迭代器:迭代器是可迭代对象的一种,它能记住每次迭代的位置,等下次迭代时,会从上次迭代的位置继续,迭代器只能往前不会后退,取完一个值后,只能取后(下)一个值,不能取前(上)一个值。
迭代器有两个基本的方法:iter()和next()。
1.1 示例01
list = [1,2,3,4]
it = iter(list)
print(next(it))
print(next(it))
print(next(it))
print(next(it))
# print(next(it))
StopIteration
1.2 迭代器对象还可以通过for循环进行遍历
list = [1, 2, 3, 4]
it = iter(list)
for x in it:
print(x, end=' ')
1.3 迭代器对象还可以通过next()函数方法实现遍历
import sys
list = [1, 2, 3, 4]
it = iter(list)
while True:
try:
print(next(it))
except StopIteration:
sys.exit()
1.4 创建一个迭代器类
思路有二,其1是iter(),返回一个特殊的迭代器对象,其2是next()返回下一个迭代器对象,并通过StopIteration异常方法标识迭代的完成结束。以下是创建一个迭代器类,初始值为1,递增1
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
1.5 StopIteration异常,用于标识迭代的完成,防止无限的循环的情况,在__next()__方法中,我们可以设置在完成指定循环次数后触发StopIteration异常来结束迭代。
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <=20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
二、生成器
在Python中,使用了yield函数被称为是生成器(generator),跟普通函数不同,生成器是一个会返回迭代器的函数,只能用于迭代操作,更为简单的理解:生成器就是一个迭代器!即生成器自动实现了"迭代器协议"(__iter__和__next__方法)。
在调用生成器运行的过程中,每次遇到yield时,函数都会暂停并保存当前所有的运行信息,返回yield值,并在下一次执行next()方法时从当前位置继续运行!调用一个生成器函数,返回的是一个迭代器对象。
yied关键字的作用:类似return,但与return又不同,yield不仅将值返回,还会记住当前生成器的执行状态(函数运行到哪一条语句,迭代到了哪一个值等),等下次再调用next时,会从上次结束的地方接着继续执行。
2.1 在函数中使用yield,类似return作用
def test():
yield 1
yield 2
yield 3
t = test()
print(next(t))
print(next(t))
print(next(t))
2.2 yield表达式
yield表达式不是什么新鲜玩意!它其实就是yield的另一个用处,使用send()方法可以向yield关键字发送数据,之后就可以使用一个"变量"来接收这个数据,示例如下
def test():
s = yield
print(s)
s1 = yield
print(s1)
a = test()
a.send(None) #相当于next(a),没有这一步骤会报错,可以理解为初始化!
#TypeError: can't send non-None value to a just-started generator
a.send("test")
2.3 通过yield函数实现斐波那契数列
import sys
def fibonacci(n):
a, b, counter = 0, 1, 0
while True:
if (counter > n ):
return
yield a
a, b = b, a+b
counter += 1
f = fibonacci(10)
while True:
try:
print(next(f), end=' ')
except StopIteration:
sys.exit()