Python之迭代器与生成器

迭代器、迭代对象、生成器关系:

 

容器(container)

容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用innot in关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如迭代器和生成器对象)在Python中,常见的容器对象有:

  • list, deque, ….
  • set, frozensets, ….
  • dict, defaultdict, OrderedDict, Counter, ….
  • tuple, namedtuple, …
  • str

从技术角度来说,当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,比如列表、集合、元组都是容器对象。

一般容器都是可迭代对象,但并非所有容器都可迭代。

可迭代对象(iterable)

实现了__iter()__方法并调用该方法能返回迭代器的对象,称为可迭代对象。

迭代器(iterator)

迭代器协议是:对象必须提供一个next方法,执行该方法要么返回迭代的下一项,要么就引起一个 StopIteration异常,以终止迭代(只能往后走 不能往前推)。

协议是一种约定,可迭代对象 实现了迭代器协议,python的内部工具(如for循环, sum , min max函数)使用迭代器协议访问对象

实现了__next__()方法并调用__next()__方法的时候返回容器中的下一个值的对象,可称为迭代器,__next__()返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常。

class Fib:
    def __init__(self):
        self.prev = 0
        self.curr = 1
 
    def __iter__(self):
        return self
 
    def __next__(self):
        value = self.curr
        self.curr += self.prev
        self.prev = value
if value > 500:
  raise(StopIteration) #引起一个 StopIteration异常
return value >>> f = Fib() >>>for i in f:
if i<20:
print(i)
#---------------
1
1
2
3
5
8
13
21

Fib是可迭代对象(实现了__iter()__方法),也是迭代器(实现了__next()__方法)。

生成器(generator)

 生成器是一种特殊的迭代器(可调用__next__()方法),生成器通过yiled返回数值,用生成器来实现斐波那契数列的例子是:

def fib():
    prev, curr = 0, 1
    while True:
        yield curr
        prev, curr = curr, curr + prev

f = fib() #生成生成器f

for i in f:
    print(i)
    if i>20:
        break
#---------------
1
1
2
3
5
8
13
21

生成器表达式(generator expression)

生成器表达式是列表推倒式的生成器版本,看起来像列表推导式,但是它返回的是一个生成器对象而不是列表对象。

a = (x**2 for x in range(6))
print(a)
#<generator object <genexpr> at 0x0000000002E3B200>
sum(a)
#55

l=[x**2 for x in range(6)]
print(l)
#[0, 1, 4, 9, 16, 25]
  • 容器是一系列元素的集合,str、list、set、dict、file、sockets对象都可以看作是容器,容器都可以被迭代(用在for,while等语句中),因此他们被称为可迭代对象。
  • 可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。
  • 迭代器持有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next____iter__方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。
  • 生成器是一种特殊的迭代器,它的返回值不是通过return而是用yield
posted @ 2018-09-11 20:23  恋853雨  阅读(107)  评论(0编辑  收藏  举报