生成器

Posted 明王不动心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生成器相关的知识,希望对你有一定的参考价值。

一、什么是生成

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

什么是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]]])))

 

以上是关于生成器的主要内容,如果未能解决你的问题,请参考以下文章

Apollo Codegen 没有找到生成代码的操作或片段

前端开发工具vscode如何快速生成代码片段

前端开发工具vscode如何快速生成代码片段

vscode代码片段生成vue模板

VS Code配置snippets代码片段快速生成html模板,提高前端编写效率

vs 2010代码片段