Python的迭代器和生成器

先说迭代器,对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的就,在后台for语句对容器对象对象调用iteration()函数,这是python的内置函数,iter()会返回一个定义next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。在没有后续元素是,调用next()会抛出一个StopIteration异常

上面说的都是python自带的容器对象,它们都实现了相应的迭代器方法,自定义类的遍历怎么实现,方法是:对这个类AClass,实现__iter__(self)方法,使其返回一个带有__next__(self)方法的对象就可以了。如果你在AClass刚好也定义了__next()__(self)方法,那在__iter__里只有返回self就可以。

__iter__()和next()方法

这两个方法是迭代器最基本的方法,一个 用来获得迭代器对象,一个用来获取容器中的下一个元素。

class MyRange(object):
  def __init__(self,n):
    self.idx=0
    self.n=n
    def __iter__(self):
    return self

  def next(self):
    if self.idx<self.n:
      val = self.idx
      self.idx +=1
      return val
    else:
      raise StopIteration()

  myRange = MyRange(3)
  for i in myRange:
    print i

myRange这个对象就是一个可迭代对象,同时它本身也是一个迭代器对象。

生成器

在Python中,使用生成器可以很方便的支持迭代器协议。生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态。

def Zrange(n):
  i = 0
  while i < n:
    yield i
    i+= 1
zrange = Zrange(3)
print zrange
print [i for i in zrange]

其实,生成器函数返回生成器的迭代器。 “生成器的迭代器”这个术语通常被称作”生成器”。要注意的是生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法,其中一个就是next()。如同迭代器一样,我们可以使用next()函数来获取下一个值。

下面就介绍生成器是怎么工作的:

def Zrange(n):
  print ‘beginning of Zrange‘
  i = 0
  while i < n:
    print ‘before yield‘,i
    yield i
    i += 1
    print ‘after yield‘,i
  print ‘endding of Zrange‘
zrange = Zrange(3)
print ‘-------------------------‘
print zrange.next()
print ‘------------------‘
print zrange.next()
print ‘------------------‘
print zrange.next()
print ‘------------------‘
print zrange.next()
print ‘------------------‘

通过结果可以看到:

  • 当调用生成器函数的时候,函数只是返回了一个生成器对象,并没有 执行。
  • 当next()方法第一次被调用的时候,生成器函数才开始执行,执行到yield语句处停止
    • next()方法的返回值就是yield语句处的参数(yielded value)
  • 当继续调用next()方法的时候,函数将接着上一次停止的yield语句处继续执行,并到下一个yield处停止;如果后面没有yield就抛出StopIteration异常

生成器的send()和close()方法

生成器中还有两个很重要的方法:send()和close()。

  • send(value):

从前面了解到,next()方法可以恢复生成器状态并继续执行,其实send()是除next()外另一个恢复生成器的方法。

Python 2.5中,yield语句变成了yield表达式,也就是说yield可以有一个值,而这个值就是send()方法的参数,所以send(None)和next()是等效的。同样,next()和send()的返回值都是yield语句处的参数(yielded value)

关于send()方法需要注意的是:调用send传入非None值前,生成器必须处于挂起状态,否则将抛出异常。也就是说,第一次调用时,要使用next()语句或send(None),因为没有yield语句来接收这个值。

  • close():

这个方法用于关闭生成器,对关闭的生成器后再次调用next或send将抛出StopIteration异常。

时间: 12-02

Python的迭代器和生成器的相关文章

python中迭代器和生成器的区别

1 #!/usr/bin/python 2 def power(values): 3 for value in values: 4 print "powing %s" % value 5 yield value 6 def add(values): 7 for value in values: 8 if value % 2 == 0: 9 yield value + 3 10 else: 11 yield value + 2 12 elements = [1, 4, 7, 9, 12,

python基础-迭代器和生成器

一.递归和迭代 1.递归:(问路示例) 递归算法是一种直接或者间接地调用自身算法的过程.在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解. 2.迭代:简单理解为更新换代( 儿子生孙子的故事) 二.迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter_

Python的迭代器与生成器

Python中的生成器和迭代器方便好用,但是平时对生成器和迭代器的特性掌握的不是很到位,今天将这方面的知识整理一下. 迭代器 为了更好的理解迭代器和生成,我们需要简单的回顾一下迭代器协议的概念. 迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 3.协议是一种约定,可迭代对象

Python之迭代器、生成器、装饰器和递归

一.迭代器&生成器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁.这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件 特点: 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容 不能随机访问集合中的某个值 ,只能从头

4.python的迭代器与生成器

一.什么玩意是迭代器? 先说说什么是迭代吧,迭代就是一件事情重复很多次,比如说for循环. for循环可以对一切有__iter__方法的对象进行迭代,那么什么是__iter__方法呢? 一个对象是否可迭代,全都取决于这个对象是否有__iter__方法,调用对象的__iter__方法,就回返回一个迭代器,这个迭代器一定具有next方法,在调用这个迭代器的next方法时,迭代器就回返回它的下一个值,当迭代器中没有值可以返回了,就回抛出一个名为StopIteration的异常,停止迭代. 迭代器还有个

python(4)-迭代器 和 生成器

迭代器是访问集合元素的一种方式.迭代器适合遍历一些巨大或无限的集合,比如几个G的文件.迭代器具有以下特点: 1. 访问者不需要关心迭代器内部的结构,只需通过__next__()方法不断取下一个内容 2. 不能随机访问集合中的某个值,只能从头到尾依次访问 3. 访问只能向前,不能后退 4. 便于循环比较大的数据集合, 节省内存 比如: with open("test.txt", 'r') as f: # f 就是迭代器 for line n f: print(line) 迭代器的方法:

python 之 迭代器和生成器(yield)

一.罗列全部的内置函数 戳:https://docs.python.org/2/library/functions.html 二.range.xrange(迭代器) 无论是range()还是xrange()都是Python里的内置函数.这个两个内置函数最常用在for循环中.例如: >>> for i in range(5): ... print i ... 0 1 2 3 4 >>> for i in xrange(5): ... print i ... 0 1 2 3

【Python之迭代器,生成器】

一.可迭代对象和迭代器 1.迭代的概念 上一次输出的结果为下一次输入的初始值,重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值 注:循环不是迭代 while True: #只满足重复,因而不是迭代 print('====>') 2.可迭代的对象 内置__iter__方法的,都是可迭代的对象. list是可迭代对象,dict是可迭代对象,set也是可迭代对象. [1,2].__iter__() 'hello'.__iter__() (1,2).__iter__() {

python 3 迭代器与生成器

import sys def fibonacci(n): a, b, counter = 0, 1, 0 while True: if (counter >= n): return a, b = b, a+b yield a counter += 1 f = fibonacci(1) while True: try: print (next(f), end=" ") except StopIteration: sys.exit() 当yield 返回迭代器之后,后面再return