python的迭代器和生成器
本文将简要介绍python中迭代器和生成器的区别与联系,以下内容基于python2.7环境
1. 可迭代对象与迭代器
1.1 可迭代对象
可迭代对象需要满足的条件:实现了 __iter__ 方法,该方法返回一个迭代器对象,可以使用for...in...循环进行取值。
例如:list, tuple, dict, str, set 等等。
1.2 迭代器
迭代器条件:实现了 __iter__ 和 next 方法。
如果调用了next方法,容器没有值可以返回,则会抛出一个StopIteration异常。
next方法的使用有两种方式:i.next() 和 next(i)。
判断方法
from collections import Iterable,Iterator print isinstance(["S","u","g","a","r"], Iterable) print isinstance(["S","u","g","a","r"], Iterator) print isinstance(iter(["S","u","g","a","r"]), Iterator) # 对于python内置的可迭代对象,可以使用函数iter()获取相应的迭代器 运行结果: True False True
代码举例1
class Test(): def __init__(self,data=1): self.data = data def __iter__(self): return self def next(self): if self.data > 5: raise StopIteration else: self.data+=1 return self.data t = Test(3) from collections import Iterator print isinstance(t, Iterator) for i in t: print i 运行结果: True 4 5 6
代码举例2(斐波那契数列)
class Fibonacci_sequence(object): def __init__(self): self.prev = 0 self.cur = 1 def __iter__(self): return self def next(self): value = self.cur self.prev,self.cur = self.cur,self.prev+self.cur return value fib = Fibonacci_sequence() print fib.next(),next(fib),fib.next(),next(fib),fib.next(),fib.next() from collections import Iterator print isinstance(fib, Iterator) 运行结果: 1 1 2 3 5 8 True
补充
#itertools函数返回的都是迭代器对象 from itertools import count,cycle from collections import Iterator counter = count(start=1, step=3) print isinstance(counter,Iterator) print next(counter) print counter.next() print next(counter) print counter.next() 运行结果: True 1 4 7 10 colors = cycle(["red","green","blue"]) print colors.next(),colors.next(),colors.next(),colors.next(),colors.next(),colors.next() 运行结果: red green blue red green blue
小结
迭代器一定是可迭代对象,可迭代对象不一定是迭代器!
迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果!
iter()和__iter__不同,iter()是直接调用了对象的__iter__方法,并且把这个方法的返回值作为自己的返回值。
在for..in...循环中,比如 for i in list,会先调用iter(list)得到可迭代对象list的迭代器,每次循环再调用迭代器的next()方法获取值。
2. 生成器
生成器是一种特殊的迭代器(更加优雅),它不需要像类一样写__iter__和next方法,只需要一个yield关键字即可,生成器一定是迭代器
2.1 生成器函数
代码举例1
def func(): a = 0 while True: yield a a += 1 f = func() # f就是一个生成器,通过调用f的next方法取值 print f.next(),next(f),next(f),next(f),next(f) 运行结果: 0 1 2 3 4
代码举例2(斐波那契数列)
def fibonacci_sequence(): prev,cur = 0,1 while True: yield cur prev,cur = cur,prev+cur fib = fibonacci_sequence() # fib是一个生成器,通过调用next方法取值 print fib.next(),fib.next(),fib.next(),fib.next(),fib.next(),fib.next(),fib.next() from collections import Iterable,Iterator print isinstance(fib, Iterable) print isinstance(fib, Iterator) 运行结果: 1 1 2 3 5 8 13 True True
2.2 生成器表达式
代码举例
generator = (i for i in range(10)) # 注意使用的是小括号而不是中括号 from collections import Iterable,Iterator print isinstance(generator, Iterable) print isinstance(generator, Iterator) 运行结果: True True
记住要仰望星空,不要低头看脚下。无论生活如何艰难,请保持一颗好奇心。你总会找到自己的路和属于你的成功。