迭代器与生成器
# 迭代是python最强大的功能之一 是访问元素集合的方式之一
# 迭代器:迭代器是一个可以记住遍历位置的对象
# 迭代器对象 从集合的第一个元素开始访问,直到所有的元素访问结束
# 迭代器只能往前 不能后退
#
# 迭代器有两个基本的方法:iter()和next()
# 字符串 列表 元组对象都可以用于创建迭代器
# iter()可以用来创建迭代器
# next()可以用来依次获取迭代器内的元素 每次按顺序拿一个
#
list1 = [1,2,3,6,7,9,7]
it = iter(list1) # 创建迭代器对象
print(it) #<list_iterator object at 0x000002008DFA9518>
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
print(next(it)) # 6
print(next(it)) # 7
print(next(it)) # 9
print(next(it)) # 7
print(next(it)) #报错 StopIteration
#
# 迭代器对象可以for循环遍历
for i in it:
print(i)
#
# 也可以使用next()函数打印
while True:
try:
print(next(it))
except StopIteration as e:
break
#
# 创建一个迭代器需要用到两个方法__iter__()和__next__()
# __iter__():方法需要返回对象本身:self
# __next__(): 返回下一个数据 如果限制迭代次数 则需要抛出StopIteration异常用来结束迭代
#
class Myiterator():
def __iter__(self):
self.num = 0
return self #返回未被实例化的对象
def __next__(self):
self.num += 1
return self.num
if __name__ == '__main__':
p = Myiterator() #创建迭代器对象
#使用iter方法转换为迭代器对象
it1 = iter(p)
print(next(it1)) #1
print(next(it1)) #2
#使用for循环遍历
for循环内部逻辑,for循环可以遍历可迭代对象
在循环内部先执行__iter__方法 在通过__next__方法逐步取值
for i in it1:
print(i) #没有限制迭代次数 导致for循环进入无限循环
#
# 限制迭代次数
class Myiterator():
def __iter__(self):
self.num = 0
return self #返回未被实例化的对象
def __next__(self):
self.num += 1
if self.num == 10:
raise StopIteration #等于10时 触发异常结束迭代
else:
return self.num
#
if __name__ == '__main__':
p = Myiterator() #创建迭代器对象
#使用iter方法转换为迭代器对象
it1 = iter(p)
for i in it1:
print(i) #1-9
#
# 生成器:是一种特殊的迭代器
# 生成器返回保留关键字yield的值
#
def func1():
yield 1
yield 2
yield 3
# 创建生成器对象
# (内部调用了生成器类generator创建的对象,
# 生成器类generator也声明了__iter__()和__next__()方法)
it1 = func1()
print(next(it1)) #1
print(next(it1)) #2
print(next(it1)) #3
print(next(it1)) #报错StopIteration
# 也可以使用for循环遍历
for i in it1:
print(i)
#
# 利用生成器函数实现斐波那契数列
# 调用生成器函数 返回一个迭代器对象
def fbnq(n):
a = 0
b = 1
c = 0
while True:
if c > n :
return
yield a #第一次a的值为a = 0 第二次 a=1
# 双向复制可以理解为 a =b b=a+b 每一次迭代更新a和b的值
a,b = b, a + b #第一次a =1 b = 1 第二次 a=1 b=2 第三次 a = 2 b=3 第四次 a=3 b=5
c += 1 #控制迭代次数
f = fbnq(10)
while True:
try:
print(next(f),end=' ') #0 1 1 2 3 5 8 13 21 34 55
except StopIteration:
break