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

 

posted @ 2018-09-22 10:19  爱吃甜食的boy  阅读(327)  评论(0编辑  收藏  举报