美文网首页
迭代,列表生成式,生成器,迭代器

迭代,列表生成式,生成器,迭代器

作者: Brucezen | 来源:发表于2020-11-09 12:59 被阅读0次
    
    '''可以判断一个对象是否可迭代对象'''
    from collections.abc import Iterable
    isinstance('abc',Iterable)
    
    '''将一个可迭代对象变成(下标,值)的元素对进行索引'''
    for i, value in enumerate('abc'):
        print(i, value)
    

    列表生成式的用法

    [x*x for x in range(1,11) if x%2 == 0] #加上if判断
    
    [m+n for m in 'ABC' for n in 'XYZ'] #使用两层循环
    Output:['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
    
    d = {'x':'A', 'y':'B', 'z':'C'}
    [k + '=' + v for k, v in d.items()] #用两个变量来生成list
    Output:['x=A', 'y=B', 'z=C']
    
    L = ['Hello','World','IBM', 'Apple']
    [s.lower() for s in L]  #把一个字符串list的元素都变成小写的
    
    '''if...else语句+for循环,记住if...else必须在for前面且此处else不能省略'''
    [x if x%2==0 else -x for x in range(1,11)]
    Out:[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
    

    关于生成器:
    列表生成式可以直接创建一个列表。但如果仅需要访问前面几个元素,那后面元素占用的空间就浪费了。
    所以,如果列表元素可以按照某种算法推算出来,可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。
    在Python中,这种一边循环一边计算的机制,称为生成器:generator。

    1. 创建生成器的第一个方法,把列表生成式的[]变为():
    L = [x**x for x in range(10)]
    g = (x**2 for x in range(10))
    # L是列表,而g是一个生成器
    print(type(L),type(g))
    out:<class 'list'> <class 'generator'>
    
    #由于generator也是可迭代对象,因此我们可以对它用for循环
    for n in g:
        print(n)
    
    1. 创建生成器的第二个方法,在函数里使用yield
    def fib(max):
        n, a, b = 0,0,1
        while n < max:
            print(b)
            a,b = b, a+b
            n += 1
        return 'done'
    
    def g_fib(max):
        n, a, b = 0,0,1
        while n < max:
            yield b
            a,b = b, a+b
            n += 1
        return 'done'
    print(type(fib),type(g_fib))
    Out:<class 'function'> <class 'function'>
    
    # 可以看到g_f是一个生成器
    g_f = g_fib(6)
    print(type(g_f))
    Out:<class 'generator'>
    

    generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
    用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

    # 用for循环调用generator时,发现拿不到函数g_fib()的返回值
    for i in g_fib(6):
        print(i)
    Out:
    1
    1
    2
    3
    5
    8
    
    '''想要拿到返回值,必须捕获StopIteration错误; 用try... except语句捕获异常StopIteration, 返回值包含在StopIteration的value中'''
    g_f = g_fib(6)
    while True:
        try:
            x = next(g_f)
            print('g_f:',x)
        except StopIteration as e:
            print('Generator return value:', e.value)
            break
    Out:
    g_f: 1
    g_f: 1
    g_f: 2
    g_f: 3
    g_f: 5
    g_f: 8
    Generator return value: done
    

    可以直接作用于for循环的数据类型有: list,tuple,dict,set,str和generator(包括生成器和带yield的generator function);这些统称为可迭代对象:Iterable,可以用isinstance()判断一个对象是否Iterable:

    from collections.abc import Iterable
    isinstance([],Iterable)
    

    生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
    可以使用isinstance()判断一个对象是否是Iterator对象:

    from collections.abc import Iterator
    isinstance((x for x in range(10)),Iterator)
    

    生成器都是Iterator对象,但list,dict,str虽然是Iterable,但却不是Iterator.可以用iter()函数把Iterable变成Iterator

    from collections.abc import Iterable, Iterator
    print(isinstance('abc', Iterator))
    print(isinstance(iter('abc'), Iterator))
    Out:
    False
    True
    

    相关文章

      网友评论

          本文标题:迭代,列表生成式,生成器,迭代器

          本文链接:https://www.haomeiwen.com/subject/myylbktx.html