Python的生成器函数详解,


目录
  • Python的生成器函数
    • 生成器的概念
    • 构造生成器
    • 生成器函数的语法糖
  • python生成器和yield语句
    • 生成器
    • 普通可迭代对象和生成器对比
    • yield语句
  • 总结

    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		
    

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持3672js教程。

    您可能感兴趣的文章:
    • Python range函数之生成器函数的示例
    • python教程之生成器和匿名函数
    • Python函数的迭代器与生成器的示例代码
    • Python函数生成器原理及使用详解
    • Python函数式编程指南:对生成器全面讲解

    评论关闭