zoukankan      html  css  js  c++  java
  • 生成器与迭代器

    生成器

                  只有在调用的时候才会生成相应的数据

                  只能逐个往后取(不能取前面的,也不能直接跳到后面)

                  取值只有一个__next()__方法(Python3)next()(Python2)

                  send()不仅能像next()读下一项,同时还能往yield发送指定内容

    两种实现方式

    1.生成器表达式,语法看似列表推导式,只是把最外层的中括号改为小括号。

    >>> a = (i for i in range(8))
    >>> a
    <generator object <genexpr> at 0x000001D1C9FB8A98>
    >>> dir(a)
    ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']

    2.函数(通过yield关键字)

    #coding=utf-8
    
    def natural_number():
        '''自然数'''
        n = 0
        while True:
            yield n
            n += 1
    
    n = natural_number()
    print n.next()
    print n.next()
    print n.next()
    print n.next()
    print n.next()
    
    0
    1
    2
    3
    4
    #coding=utf-8
        
    def fib(x):
        # 斐波拉契数列
        n, a, b = 0, 0, 1
        while n < x:
            yield b
            a, b = b, a + b
            n += 1
    
    f = fib(6)
    print f.next()
    print f.next()
    print f.next()
    print f.next()
    print f.next()
    print f.next()
    
    1
    1
    2
    3
    5

     通过yield在单线程的情况下实现并发运算的效果

    #coding=utf-8
    
    # 生产者消费者模型
    def write_code(name):
        print '注意了!{}要开始写代码了!'.format(name)
        rc_1 = read_code('华哥', '测试')
        rc_2 = read_code('', '解决')
        rc_1.next()
        rc_2.next()
        for i in xrange(1, 7):
            print '{}写了{}行代码!'.format(name, i)
            rc_1.send(i)
            rc_2.send(i)
    
    def read_code(name, type):
        print '{}在旁边帮辉哥{}bug!'.format(name, type)
        while True:
            line = yield
            print '{}已经{}了{}个bug'.format(name, type, line)
    
    write_code('辉哥')

    注意了!辉哥要开始写代码了!
    华哥在旁边帮辉哥测试bug!
    我在旁边帮辉哥解决bug!
    辉哥写了1行代码!
    华哥已经测试了1个bug
    我已经解决了1个bug
    辉哥写了2行代码!
    华哥已经测试了2个bug
    我已经解决了2个bug
    辉哥写了3行代码!
    华哥已经测试了3个bug
    我已经解决了3个bug
    辉哥写了4行代码!
    华哥已经测试了4个bug
    我已经解决了4个bug
    辉哥写了5行代码!
    华哥已经测试了5个bug
    我已经解决了5个bug
    辉哥写了6行代码!
    华哥已经测试了6个bug
    我已经解决了6个bug

    迭代器

    可迭代对象(Iterable):可作用于for循环的对象统称为可迭代对象

    迭代器(Iterator):可以被next()函数调用并不断返回下一个值的对象成为迭代器

                                生成器都是可迭代对象,但list, tuple, str不是,可以通过iter()函数转换

    instance可以判断某对象是否为可迭代对象或者是否为迭代器

    #coding=utf-8
    
    from collections import Iterable, Iterator
    
    a = dict()
    print '变量a是一个可迭代对象:', isinstance(a, Iterable)
    print '变量a是一个迭代器:', isinstance(a, Iterator)
    
    b = (x for x in xrange(6))
    print '变量b是一个可迭代对象:', isinstance(b, Iterable)
    print '变量b是一个迭代器:', isinstance(b, Iterator)
    
    变量a是一个可迭代对象: True
    变量a是一个迭代器: False
    变量b是一个可迭代对象: True
    变量b是一个迭代器: True
  • 相关阅读:
    php自动保存文章内容中的图片
    javascript中字符串操作函数
    iis 301永久重定向图文教程
    ORA27101,ORA27102 错误解决方法
    IIS中启用Gzip压缩传输网页方法
    asp.net抓取163邮箱联系人实现代码
    windows IIS 日志文件如何查看及分析
    输出页面所有HTML 包括 JS 添加 的内容
    VS2005无法启动调试 及 解决办法
    Json转行DataTable
  • 原文地址:https://www.cnblogs.com/allenzhang-920/p/8922662.html
Copyright © 2011-2022 走看看