python中的generator, iterator, iterabel

先来看看如果遇到一个对象,如何判断其是否是这三种类型:

1 from types import GeneratorType
2 from collectiuons import Iterable, Iterator
3
4 isinstance( xx, GeneratorType )
5 isinstance( xx, Iterable )
6 isinstance( xx, Iterator )

生成器对象:

  生成器是一个通过yield关键字构建的函数,其返回一个generator对象,同时其又是一个iterator对象,因为其实现了__iter__与next方法

In[4]: def gene(k):
...     for i in xrange(0, k):
...         yield i
...
In[5]: ge = gene(6)
In[6]: type(ge)
Out[6]: generator
In[8]: dir(ge)
Out[8]: [ ...,‘__iter__‘, ‘next‘, ... ]
In[9]: isinstance(ge, collections.Iterator)
Out[9]: True

  生成器的一个特点是只能用一次

In[11]: for i in ge:
...     print i
...
0
1
2
3
4
5
In[12]: ge.next()
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/IPython/core/interactiveshell.py", line 2820, in run_code
    exec code_obj in self.user_global_ns, self.user_ns
  File "<ipython-input-12-b9172cd6050f>", line 1, in <module>
    ge.next()
StopIteration

迭代器对象:

  实现了__iter__与__next__方法的对象。

  __iter__返回一个实例作为最终使用的iterator对象--for...in...语句初始化时使用,next方法是后面每次迭代iterator对象时调用的方法

class Counter(object):
    def __init__(self, low, high):
        self.current = low
        self.high = high

    def __iter__(self):
        # ‘Returns itself as an iterator object‘
        return self

    def next(self):
        # ‘Returns the next value till current is lower than high‘
        if self.current > self.high:
            raise StopIteration
        else:
            self.current += 1
            return self.current - 1
>>> c = Counter(5,10)
>>> for i in c:
...   print(i, end=‘ ‘)
...
5 6 7 8 9 10>>> for i in c:...  pritn i...# 无输出>>> c.next()
Traceback (most recent call last):
  File "<ipython-input-12-b9172cd6050f>"
    c.next()
StopIteration

可迭代对象:

  可迭代对象就是用于for...in...循环的

  不同于上面两种,其需要可以多次for...in...使用

  通过generator写可迭代对象:

  将__iter__写成生成器函数。注意for...in...时初始化时调用__iter__函数使得counter为low, 而后执行的都是yield所影响区域的了【1】,除非下次再执行for...in...语句才会调用到counter初始化那句,这样也就实现了复用。但是有个问题是此时Counter的实例就既不是generator也不是iterator对象了。故其也没法调用next方法

class Counter(object):
    def __init__(self, low, high):
        self.low = low
        self.high = high

    def __iter__(self):
        counter = self.low
        while self.high >= counter:
            yield counter
            counter += 1

obj = Counter(5, 10)
print isinstance(obj, Iterator)
print isinstance(obj, GeneratorType)
print type(obj)
for i in obj:
    print iobj.next()

False
False
<class ‘__main__.Counter‘>
5
6
7
8
9
10

Traceback (most recent call last):
File "/home/pd/..."
obj.next()
AttributeError: ‘Counter‘ object has no attribute ‘next‘

注释【1】:

In [1]: def gener(k):
   ...:     print "====initial===="
   ...:     for i in range(0, k):
   ...:         print "before yield"
   ...:         yield i
   ...:         print "after yield"
   ...:     print "*****end******"
   ...:                                                                          

In [2]: g = gener(3)
In [3]: for i in g:
   ...:     print g
   ...:
====initial====
before yield
<generator object gener at 0x7fbc8d15e870>
after yield
before yield
<generator object gener at 0x7fbc8d15e870>
after yield
before yield
<generator object gener at 0x7fbc8d15e870>
after yield
*****end****** 

参考:

  http://pymbook.readthedocs.io/en/latest/igd.html

时间: 2024-11-03 10:06:19

python中的generator, iterator, iterabel的相关文章

python中的generator(coroutine)浅析和应用

背景知识: 在Python中一个function要运行起来,它在python VM中需要三个东西. PyCodeObject,这个保存了函数的代码 PyFunctionObject,这个代表一个虚拟机中的一个函数对象 PyFrameObject,这个代表了函数运行时的调用链和堆栈 Python正是通过这三样东西模拟0x86的函数调用的 在python中 coroutine(协程)被称为的generator,这两个东西在python其实是同一个东东,之所以如此称呼是因为它有迭代器的功能,但是又可以

【Python笔记】如何理解python中的generator functions和yield表达式

本篇笔记记录自己对Python的generator functions和yield表达式的理解. 1. Generator Functions Python支持的generator functions语法允许我们定义一个行为与iterator类似的函数,它可以被用在需要循环调用的场合.与普通函数相比,generator functions只是在函数定义中多了1个yield表达式,除此之外,没有其它特别之处. 当generator函数被创建时,python解释器会自动为它实现iteration p

python中的生成器(generator)总结

1.实现generator的两种方式 python中的generator保存的是算法,真正需要计算出值的时候才会去往下计算出值.它是一种惰性计算(lazy evaluation). 要创建一个generator有两种方式. 第一种方法:把一个列表生成式的[]改成(),就创建了一个generator: >>> L = [x * x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>

python中yield用法

在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发 StopIteration.任何这类的对象在Python中都可以用for循

Python中yield

在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(Generator). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何"可迭代对象",这其实就是迭代器 迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发 StopIteration.任何这类的对象在Python中都可以用f

【转载】关于Python中的yield

在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发 StopIteration.任何这类的对象在Python中都可以用for循

Python之生成器(generator)和迭代器(Iterator)

generator 生成器generator:一边循环一边计算的机制. 生成器是一个特殊的程序,可以被用于控制循环的迭代行为.python中的生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,可以使用next()函数和send()函数恢复生成器. 生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用.但是,不同于一般函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这个消耗的内存数量将大大减小.因此,生成器看起来像是一个函数,但是表现得像迭代

Python生成器(generator)和迭代器(Iterator)

列表生成式 a = [i+1 for i in range(10)] print(a) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 这就是列表生成式 生成器(generator) 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的. 如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的    list,从而节省大量的空间.在Python中,这种一边循环一边计算的机制,称为生成器(gene

python中 Lambda,Map,Filter,Itertools,Generator高级函数的用法

Lambda 函数 Lambda 函数是一种比较小的匿名函数--匿名是指它实际上没有函数名. Python 函数通常使用 def a_function_name() 样式来定义,但对于 lambda 函数,我们根本没为它命名.这是因为 lambda 函数的功能是执行某种简单的表达式或运算,而无需完全定义函数. lambda 函数可以使用任意数量的参数,但表达式只能有一个. x = lambda a, b : a * b print(x(5, 6)) # prints '30' x = lambd