• 生成器


    一、什么是生成

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

    什么是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的部分,生成器的迭代器是这个函数返回的部分。

  • 相关阅读:
    第十二节:类的定义
    第十二节:类的定义
    第十二节:类的定义
    Android核心技术Intent和数据存储篇
    Android核心技术Intent和数据存储篇
    Android核心技术Intent和数据存储篇
    ObjectDataSource配置数据源的时候,选择业务对象下拉菜单没有任何东西
    两个时间相差多少 .net中的timespan应用
    net3:DropDownList的动态绑定
    ADO:DataSet存入缓存Cache中并使用
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/7774280.html
Copyright © 2020-2023  润新知