所谓迭代,就是一个循环,厉遍数据结构(列表,字典,元组等)内元素的过程。字符串,列表,字典,元组,集合都是可迭代对象。
而迭代器是用与迭代操作(for循环)的对象。可迭代对象通过__iter__方法转变成迭代器,迭代器可以通过next()方法不断返回下一个元素直至结束。迭代器的优势在于它不像列表那样会预先就把列表内的所有元素加载到内存里,而是只在需要的时候(调用next的时候)才进行计算。
用斐波那契数列举例:
class Fib:
def __init__(self):
self.prev = 0
self.curr = 1
def __iter__(self): #转化成迭代器
return self
def __next__(self):
self.prev,self.curr = self.curr,self.prev + self.curr
return self.curr
fib = Fib()
for i in range(10):
print(next(fib))
可以看到最后还是要用for循环不断调用 next()方法来返回下一个值
生成器是一种更高级的迭代器,它用yield来返回值,它让代码以更简洁的形式呈现。每次运行到 yield 的时候,函数会暂停,并且保存当前的运行状态,返回当前的数值,并在下一次执行 next 方法的时候,又从当前位置继续往下走。
def test():
for i in range(3):
print("before yield",i)
yield i
print("after yield",i)
print("end")
f= test()
next(f)
这里第一次调用next方法时,输出为“before yield 0”
第二次再调用next方法时,输出为after yield 0 以及 before yield 1
可见每次运行到yield时都会暂停
再举个例子,比如我们要写一个返回平方数的函数,如果用普通方法写,又要创建空的列表,还要把每次的计算结果放进去
def square(n):
sq=[]
for i in range(n):
sq.append(i**2)
return sq
for i in square(5):
print(i)
如果用生成器写:
def square(n):
for i in range(n):
yield i**2
for i in square(5):
print(i)
两者的区别在于,普通方法是先全部计算好再吧结果呈现出来,而生成器是先计算一次呈现一次,用网上某位网友的话说,就是一桌菜全部炒完再上和炒一个上一个的区别
同样再来看刚才的斐波那契数列的例子,用生成器写:
def fib():
prev, curr = 0, 1
while True:
yield curr
curr, prev = prev + curr, curr
f = fib()
for i in range(10):
print(next(f))