码迷,mamicode.com
首页 > 其他好文 > 详细

迭代器生成器

时间:2018-02-01 13:09:43      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:list   exp   自身   迭代器   return   yield   col   sum   rabl   

容器(container)、可迭代对象(iterable)、迭代器(iterator)、生成器(generator)

技术分享图片

大多数容器都提供了某种方式来获取其中的每一个元素,但是这并不是容器本身提供的能力,而是可迭代对象赋予了容器的这种能力

可迭代对象(iterable)[可迭代对象的内部实现了__iter__方法,该方法返回一个迭代器对象]

>>> x = [1, 2, 3]
>>> y = iter(x)
>>> z = iter(x)
>>> next(y)
1
>>> next(y)
2
>>> next(z)
1
>>> type(x)
<class ‘list‘>
>>> type(y)
<class ‘list_iterator‘>

迭代器是具有迭代类型,比如list_iteratorset_iterator

举例说明:

x = [1, 2, 3]
for elem in x:
    ...

真实的情况是:

技术分享图片

反编译该段代码,你可以看到解释器显示地调用GET_ITER指令,相当于调用iter(x)FOR_ITER指令就是调用next()方法,不断地获取迭代器中的下一个元素,但是你没法直接从指令中看出来,因为他被解释器优化过了。

 

迭代器(itertor)

迭代器是一个带状态的对象,任何实现了__iter__ 和 __next__(python2中实现了next())方法的对象都是迭代器。__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多的元素,则抛出异常。

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
        return value
 
>>> f = Fib()
>>> list(islice(f, 0, 10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Fib既是一个可迭代对象(实现了__iter__方法),又是一个迭代器实现了(__next__方法),实例变量prev和curr用户维护迭代器内部的状态,每一次调用next()方法的时候做两件事:

  1、为下一次调用next()方法修改状态

  2、为当前这次调用生成返回结果

生成器(generator)

生成器是一种特殊的迭代器,不过这种迭代器显得更加优雅,生成器不需要写__iter__和__next__方法,只需要一个yield关键字。

生成器一定是迭代器(反之不成立)

 

生成器表达式(generator expression)

生成器表达式是列表推导式的生成器版本

>>> a = (x*x for x in range(10))
>>> a
<generator object <genexpr> at 0x401f08>
>>> sum(a)
285

 

总结:

* 容器是一系列元素的集合,str、list、set、dict、file、sockets都可以看作是容器

  容器都是可以被迭代的

* 可迭代对象实现了__iter__ 方法,该方法返回一个迭代器对象

* 迭代器持有一个内部状态字段用户记录下次迭代返回值它实现了 __iter__ 和 __next__方法,迭代器不会一次性把所有的元素加载到内存,而是需要的时候才返回结果

* 生成器是一种特殊的迭代器,返回值是通过yeild

 

迭代器生成器

标签:list   exp   自身   迭代器   return   yield   col   sum   rabl   

原文地址:https://www.cnblogs.com/mosson/p/8398187.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!