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
  • 相关阅读:
    使用 requests 维持会话
    使用 requests 发送 POST 请求
    使用 requests 发送 GET 请求
    requests 安装
    使用 urllib 分析 Robots 协议
    使用 urllib 解析 URL 链接
    使用 urllib 处理 HTTP 异常
    使用 urllib 处理 Cookies 信息
    使用 urllib 设置代理服务
    按单生产程序发布
  • 原文地址:https://www.cnblogs.com/allenzhang-920/p/8922662.html
Copyright © 2011-2022 走看看