• 迭代器和生成器


     
    可迭代对象:可以直接作用于for循环的对象,称为可迭代对象。
         
    可以直接用for循环的数据类型有:
    1. 集合数据类型,字符串,列表,元祖,字典,集合等。(都是Iterable对象,但不是Iterator,但是可以通过iter()变成Iterator对象)
    2. generator,包括生成器和带yield的generator function。 (调用返回一个Iterator)

    可迭代对象都有一个__iter__方法 

    例如:
    >>> dir([]) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    判断一个对象是否是Iterable可迭代对象可以使用 isinstance() 方法
    from collections import Iterable
    >>> isinstance([],Iterable)
    True
    >>> isinstance({},Iterable)
    True
    >>> isinstance((x for x in range(5)),Iterable)
    True
     
     
     
    迭代器 Iterator:可以被__next__() 函数调用并不断返回下一个值的对象
     
    可以使用isinstance()判断一个对象是否是Iterator
    >>> from collections import Iterator
    >>> it=(x for x in range(1,3))
    >>> it
    <generator object <genexpr> at 0x7fed717c9db0>   
    >>> isinstance(it,Iterator)        
    True
    
    >>> isinstance([],Iterator)
    False
    迭代器特点:
    • 不能随机访问集合中的某个值,只能从头到尾依次访问
    • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。只往前进不能后退
    • 仅仅在迭代到某个元素时才会计算它,不需要事先准备所有的元素。便于循环比较大的数据集合,节省内存。类似cat,more命令。

    可迭代对象不一定是迭代器,迭代器一定是可迭代对象。

    迭代器除了有__iter__方法,还有__next__方法

    >>> it = iter(['a','b','c'])
    >>> it
    <list_iterator object at 0x7fd5bb4f76a0>
    >>> dir(it)
    ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']

    可以通过iter()将Iterable变成Iterator
    # a.__next__()输出迭代器的下一个元素  等同于2.7里next(a)
    >>> b= ('lily','jack','kang')
    >>> a = iter(b) >>> a <tuple_iterator object at 0x7fed717cbf98> >>> next(a) #2.7写法 ,3里面用__next__() 'lily' >>> a.__next__() 'jack' >>> a.__next__() ## 已迭代完所有元素,再执行会报错StopIteration 'kang' >>> next(a) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
    # 迭代器也可以用for语句遍历
    a = iter(('lily','jack','kang'))
    for i in a:
        print(i,end=' ')
     

    生成器:一个函数调用返回一个迭代器,这个函数就是生成器(generator)
    • 生成器是可以迭代的 但是只可以读取一次
    生成器表达式:
    >>> ge = (x for x in range(5))   #生成器使用 ()  区别于列表推导式[]
    >>> ge
    <generator object <genexpr> at 0x7fe0b4417048>
    >>> ge.__next__()
    0
    >>> ge.__next__()   #可以通过__next__()方法不断返回下一个
    1
    >>> for i in ge:   #也可以用for循环
    ...     print(i)
    ... 
    2
    3
    4

    生成器函数

    普通函数与生成器函数的区别:
    普通函数调用直接返回一个结果,generator函数调用返回一个迭代器

    # 遇到yield语句就返回,再次执行时从上次返回的yield语句处继续执行

    def foo(num):
        while num > 0:
            num -= 1
            yield num     #return跳出循环后不能再返回,但是yield跳出此次循环还可以继续下一次
            print('减少1')
    f = foo(3)    # 此时没有真正执行函数,只是把f变成一个迭代器
    print(f.__next__())
    print('-----')
    print(f.__next__())
    print(f.__next__())
    
    ------------->
    2
    -----
    减少1
    1
    减少1
    0
     
    def odd():
        print('step1')
        yield 1            #运行完yield1停止
        print('step2')     #下一次执行从yield1后面开始执行
        yield 3
        print('step3')
        yield 5
    o=odd()
    print(next(o))   
    ------->
    step1
    1
    
    print(next(o))
    -------->
    step2
    2
    ........................................................................
    
    def gen(func):
        for i in range(func):
            yield i
    
    for x in gen(5):
        print(x,end=' ')
    ---->
    0 1 2 3 4
    
    
    #!/usr/bin/python3
    def func():
        print('----start-------')
        a,b=0,1
        for i in range(4):
                print('1')
                yield b
                print('2')
                a,b=b,a+b
                print('3')
        print('------stop-----')
    
    f=func()
    print(next(f))
    print(next(f))
    print(next(f))
    print(next(f))
    
    --------------------输出-----start-------
        #print('1')
        #yeild b  返回1 第一次迭代完成
        #print('2') 下一次迭代从yeild b 后面开始
        #print('3')
        #print('1')
        #yeild b  第二次迭代完成
    3
    2     #yeild b 第三次迭代完成
    3
    3     #yeild b 第四次迭代完成
    View Code





  • 相关阅读:
    cocos2dx中的精灵CCSprite
    Mark Russinovich 的博客:Windows Azure 主机更新:原因、时间和方式
    cocos2d-x中的尺寸之三
    cocos2d-x中的尺寸之二
    cocos2d-x中的尺寸之一
    cocos2d-x中的导演、场景、层和精灵
    宣布正式发布 Windows Azure 上的 Oracle 软件以及 Windows Azure Traffic Manager 更新
    Hello China操作系统STM32移植指南(三)
    Hello China操作系统STM32移植指南(二)
    diff_mysql_table_exec.py
  • 原文地址:https://www.cnblogs.com/xiaobaozi-95/p/9041872.html
Copyright © 2020-2023  润新知