zoukankan      html  css  js  c++  java
  • python语法31[iterator和generator+yield]

    一 iterator迭代器

    1) 迭代器是实现了迭代器协议的某种类型,一般需要实现如下两个方法
    (1)在python2.x中,next方法,在python3.x中,为__next__(),返回容器的下一个元素
    (2)__iter__方法,返回迭代器自身
    通常的iterator与for关键字配合使用,for语句在容器对象中调用__iter__()函数返回一个定义了next()或__next__()方法的iterator。通过iterator的next()或__next__()方法来在容器中逐一访问元素,没有后续元素,next()或__next__()就会抛出一个异常,告知for循环结束。

    2)iterator的使用

    def TestIterator():
      
    for e in [24816]  :
       
    print(e)
      
    for c in 'ABCDEFG' :
        
    print (c)
        
      
    #use list iterator
      for line in open("test.txt").readlines():
        
    print (line )
        
      
    #use file iterator, and it is better. not read all data into memory
      for line in open("test.txt"):   
        
    print (line )

    #TestIterator()

    3) 自定义iterator类型

    python2.7 实例:

    class MyIterator():
      
    def __init__(self, step):
        self.step 
    = step
      
      
    def next(self):
        
    if self.step==0:
          
    raise StopIteration
        self.step
    -=1
        
    return self.step

      
    def __iter__(self):
        
    return self

    myI 
    = MyIterator(4)
    for e in myI:
      
    print e

    在python2.7下运行正常,但是在3.1下有next需要改为__next__,有错误如下:TypeError: iter() returned non-iterator of type 'MyIterator'

    python3.1代码如下:

    class MyIterator():
      
    def __init__(self, step):
        self.step 
    = step
      
      
    def __next__(self):
        
    if self.step==0:
          
    raise StopIteration
        self.step
    -=1
        
    return self.step

      
    def __iter__(self):
        
    return self

    myI 
    = MyIterator(4)
    for e in myI:
      
    print (e)

    二 generator

    1. 有yield关键字的函数则会被识别为generator函数,此时其实函数返回的仍然是iterator。
    2. generator函数用来生成一个序列,但不是一次完成,而是经过多次调用:调用generator函数得到一个generator的对象。之后每次调用generator的next()或__next__()方法都会得到序列的下一个值。
    3. 如何做到的?
    generator的next()或__next__()导致generator函数被调用,遇到yield,返回序列一个值,然后generator函数挂起。下一个next()或__next__()让generator函数恢复,从挂起处往后继续执行。

    这样做的好处之一是不必一次生成序列所有元素(例如序列很长时,存所有元素并不好),而是像有一个iterator一样一个个生成。

    1)实例

    def TestGenerator(l):
      
    for e in l:
       
    print ("before yield:" + str(e))
       
    yield e
       
    print ("after yield:" + str(e))
       
    for el in TestGenerator([6,7,8,9]):
      
    print (el)
      
    #break

    运行结果如下:
    before yield:6
    6
    after yield:6
    before yield:7
    7
    after yield:7
    before yield:8
    8
    after yield:8
    before yield:9
    9
    after yield:9

    2)实例

    def Generator2(l):
      
    for e in l:
        
    print ("before yield:" + str(e))
        enew 
    = yield e
        
    print ("after yield:" + str(enew))
      
    def TestGenerator2():
    it 
    = Generator2([6,7,8,9])
    for i in range(6,10):
      
    if i == 8 :
        element 
    = it.send(800)
      
    else:
        element 
    = it.next()
      
    print(element)

    在python2.7下运行正常,但是在3.1下需要next()改为__next__(),否则有错误如下:AttributeError: 'generator' object has no attribute 'next'

    运行结果:
    before yield:6
    6
    after yield:None
    before yield:7
    7
    after yield:800
    before yield:8
    8
    after yield:None
    before yield:9
    9

    3)实例

    def counter(maximum):
        i 
    = 0
        
    while i < maximum:
            val 
    = (yield i)
            
    # If value provided, change counter
            if val is not None:
                i 
    = val
            
    else:
                i 
    += 1

    def TestCounter():
        co 
    = counter(10)
        
    for e in co:
          
    print (e)
          
    if(e == 2):
            co.send(
    8)
      
    TestCounter()

    运行结果:

    0
    1
    2
    9

    4)next()或__next__()和send()方法作用大致是相同,next()或__next__()相当于send(None)。

    参考:

    http://www.lfyzjck.com/2010-10-23/360.html

    http://www.tech126.com/python-yileld/

    http://lukejin.javaeye.com/blog/587051

    http://www.i7xh.com/2009/10/22/py_iter/

    http://blog.csdn.net/chszs/archive/2009/01/24/3852669.aspx

    http://hi.baidu.com/uestcfb/blog/item/4f138fd314ed26043bf3cfd3.html

    完!

  • 相关阅读:
    iOS多图上传
    iOS强制横屏
    pod导入融云路径报错解决办法
    iOS 制作一个动态库
    iOS ProtocolBuffer使用介绍
    iOS 静态库与动态库的区别
    pod命令创建私有库详解【引用其他私有库、oc、Swift混编】
    M1 安装homebrew详解
    M1 执行pod install 报错
    iOS 消息转发机制
  • 原文地址:https://www.cnblogs.com/itech/p/1939119.html
Copyright © 2011-2022 走看看