zoukankan      html  css  js  c++  java
  • 生成器

    一、什么是生成

    生成器是一种用普通的函数语法定义的迭代器。

    什么是Python式的生成器?从语法上讲,生成器是一个带yield语句的函数。

    一个函数或者子程序只返回一次,但一个生成器能暂停执行并返回一个中间的结果——那就是yield语句的功能,返回一个值给调用者并暂停执行。

    当生成器的next()方法被调用的时候,他会准确的从离开的地方继续。

    生成器不会把结果保存在一个系列中,而是保存生成器的状态,在每次进行迭代时返回一个值,直到遇到StopIteration异常结束。

    生成器表达式能做的事情列表解析基本都能处理,只不过需要处理的序列比较大时,列表解析比较费内存。

    生成器函数:在函数中如果出现了yield关键字,那么该函数就不再时普通函数,而是生成器函数。

    但是生成器函数可以产生一个无线的序列,这样列表根本没有办法进行处理。

    yield的作用就是把一个函数变成一个generator,带有yield的函数不再是一个普通函数。python解释器会将其视为一个generator。

    如果要打印一列数,用函数这样写:

    def fibs(num):
        result = [0,1]
        for i in range(num-2):
            result.append(result[-2]+result[-1])
        return result
    print(fibs(10))
    执行结果:
    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

    函数只能返回一次,所以必须返回一个阵列。如果换成生成器,就可以一次返回一个值,不断返回多次。如果使用生成,它就会不断地调用生成器对象的next()方法。

     二、创建一个简单的生成器

    #使用生成器打印表中所有的值。
    def flatten(nested):
        for sublist in nested:
            for element in sublist:
                yield element
    
    nested = [[1,2,3],[4,5],(6,7)]
    for num in flatten(nested):
        print(num)
    
    #执行结果
    1
    2
    3
    4
    5
    6
    7

    如果用列表解析也能实现:

    for m in nested:
        for n in m:
            print(n)

    如果是多层,该如何实现了?——递归生成器

    三、递归生成器

    上面所讲述的生成器可以处理多层嵌套。如何处理任意层嵌套了?

    def flatten(nested):
        try:
            for sublist in nested:
                for element in flatten(sublist):
                    yield element
        except TypeError:
            yield  nested
    
    nested = [[1,2],[[11],3,4,(8,9,10),5]]
    
    for i in flatten(nested):
        print(i)

    当flatten被调用时,有两种可能性:基本情况和需要递归的情况。在基本的情况中,函数被告知展开一个元素(比如一个数字),这种情况下,for循环会引发一个TypeError异常,因为试图对一个数字进行迭代,生成器会产生一个元素。如果展开的是一个列表(或者其它可迭代对象),那么就要进行特殊处理。程序必须便利所有的子列表(可能不是列表),并对调用flatten。然后使用另一个for循环来产生被展开的子列表中的所有元素。

    def flatten(nested):
        try:
            try:nested + ''
            except TypeError:pass
            else: raise TypeError
            for sublist in nested:
                for element in flatten(sublist):
                    yield element
        except TypeError:
            yield nested
    
    print(list(flatten(['foo',['bar',['baz','1','2']]])))

    四、通用生成器

    生成器是一个包含yield关键字的函数。当它被调用时,在函数体中的代码不会被执行,而是返回一个迭代器。

    每次请求一个值,就会执行生成器中的代码,直到遇到一个yield或者return语句,yield语句意味着应该生成一个值,return语句意味着生成器要停止执行。

    生成器是由两部分组成:生成器的函数和生成器的迭代器。生成器的函数是用def语句定义的,包含yield的部分,生成器的迭代器是这个函数返回的部分。

  • 相关阅读:
    帆软—ORA-28040: No matching authentication protocol;
    Vmware虚拟机三种网络模式详解(转)
    ABAP—权限对象设计及权限检查
    ABAP—SM30维护表时提示“客户XXX有“不可修改”的状态”
    ABAP—SM维护表及标题“+”处理
    NC—语义模型调用存储过程(转)
    ABAP—多页签SHEET、选项参数或block隐藏
    oracle—聚合函数(max、min、avg、sum、count)
    oracle—decode、nvl、rownum、like、all、any使用
    从零开始的react入门教程(七),react中的状态提升,我们为什么需要使用redux
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/7774280.html
Copyright © 2011-2022 走看看