• Python生成器和迭代器


     1、生成器

     通过列表生成式,我们可以直接创建一个列表。但是,受到内存的限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占有很大的存储空间,如果我们仅仅访问前面几个元素,那后面绝大元素占用的空间都白白浪费。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素?这样就不必须创建完整的list,从而节省大量的空间。在Python中,这样一边循环一边计算的机制,称为生成器:generator。

    要创建一个generator有很多种方法。第一个方法很简单,只要把一个列表的[]改为(),就创建了一个generator:

    >>> L = [x*x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g = (x*x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x7fafe19d2410>
    

    如果要一个一个打印出生成器的元素,可以通过next()函数获得:

    >>> next(g)
    0
    >>> next(g)
    1
    >>> next(g)
    4
    >>> next(g)
    9
    >>> next(g)
    16
    >>> next(g)
    25
    >>> next(g)
    36
    >>> next(g)
    49
    >>> next(g)
    64
    >>> next(g)
    81
    >>> next(g)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    

    每次调用next(),就计算出g的下一个元素,知道计算到最后一个元素,没有更多元素,就会报错。

    #!/usr/bin/env python
    
    g = (x*x for x in range(10))
    for n in g:
        print(n)
    
    ====================================
    0
    1
    4
    9
    16
    25
    36
    49
    64
    81
    

    所以通常都是用for循环来迭代它。

    裴波拉切数列用列表生成式写不出来,但是用函数可以:上面的函数和generato仅一步之遥

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            print(b)
            a, b = b, a + b
            n = n + 1
        return 'done'
    

    注意赋值语句:

    a, b = b, a + b
    

    相当于:

    t = (b, a + b) # t是一个tuple
    a = t[0]
    b = t[1]

    上面的函数和generato仅一步之遥,只需要把print(b)改为yield b就可以了
    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
        return 'done'
    


    2、迭代器 

    可以直接作用于for循环的对象统称为可迭代对象:Iterable。

    可以使用Isinstance()判断一个对象是否为Iterable对象。

    >>> from collections import Iterable
    >>> isinstance([],Iterable)
    True
    >>> isinstance({},Iterable)
    True
    >>> isinstance('abc',Iterable)
    True
    >>> isinstance(100,Iterable)
    False
    >>> 
    

    可以被next()函数调用并返回下一个值得对象称为迭代器:Iterator。

    可以使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator
    >>> isinstance((x for x in range(10)),Iterator)
    True
    >>> isinstance([],Iterator)
    False
    >>> isinstance({},Iterator)
    False
    
  • 相关阅读:
    linux内核(四)内存管理单元MMU
    open函数详解
    linux内核(三)文件系统
    C++中数字与字符串之间的转换 scanf string总结(复习必读)
    hello程序的运行过程-从计算机系统角度
    剑指offer第12题打印从1到n位数以及大整数加法乘法
    2017-10-11第二次万革始面经
    为什么需要半关闭
    Ubuntu指令
    143. Reorder List
  • 原文地址:https://www.cnblogs.com/caicairui/p/7571274.html
Copyright © 2020-2023  润新知