插件窝 干货文章 Python的生成器函数详解

Python的生成器函数详解

生成器 class yield 函数 801    来源:    2024-10-17

Python的生成器函数

生成器的概念

生成器是Python中的一个对象,对这个对象进行操作,可以依次生产出按生成器内部运算产生的数据。

但是要注意,如果不对生成器进行操作,是不会产生数据的。

称这样的方式为惰性求值,延或者迟求值。

构造生成器

  • 生成器表达式

以前学过一种方式叫生成器表达式,例如:

g1 = (x*2 for x in range(5))
next(g1)
0
next(g1)
2
...

这就不说了。

  • 生成器函数

生成器函数,就是说定义函数时,内部带yield就算生成器函数。

每次返回的值就是yield后面的值,例如:

def g2():
    for x in range(5):
        yield x*2

list(g2)
[0, 2, 4, 6, 8]

这个yield很牛逼,和return一样,遇到之后就返回后面的值,但是yield会记住当时执行到哪里了,下一次执行从这个地方开始(就是生成器的特点)。

生成器函数的语法糖

就是yield from 语法,一种看起来简洁的表达形式吧。

普通形式的生成器函数:

def inc1():
    for x in range(10000):
        yield x

相当于

def inc2():
    yield from range(10000)

也就是说,yield from iterable 相当于 yield item for item in iterable

python生成器和yield语句

生成器

  • 生成器是可以动态(循环一次计算一次返回一次)提供数据的可迭代对象(所以属于可迭代对象,即有__iter__()和__next__())
  • 不必创建容器存储完整的结果,而节省内存空间(延迟/惰性操作)
  • 含有yield语句的函数为生成器函数,返回值为生成器对象

普通可迭代对象和生成器对比

定义函数,获取列表中所有偶数

list01 = [4,54,65,6,76,87,9]

#传统方式
def get_even01():
    #做一个容器来存储数据
    result = []
    for item in list01:
        if item % 2 == 0:
            result.append(item)
    return result

re = get_even01()
for item in re:
    print(item)

#使用生成器技术
def get_even02():
    for item in list01:
        if item % 2 == 0:
            yield item  #yield是生成器的关键词

re = get_even02()   #返回一个生成器对象
for item in re: #使用for来迭代re,因为生成器也是可迭代对象(有__iter__()方法)
    print(item)

使用生成器的最大作用是节省内存

yield语句

def f1():
    for i in range(2):
        yield i
        
g = f1()    

print(g.__next__()) #0
print(g.__next__()) #1
print(g.__next__()) #抛出异常StopIteration

#为了不抛出异常,改写上面的代码
def f1():
    for i in range(2):
        yield i
g = f1()
while True:
    try:
        print(g.__next__())
    except Exception as e:  #捕获异常,结束循环
        break       

总结

以上为个人经验,希望对您有所帮助。