首页 > 编程语言 >Python——第四章:生成器(generator)

Python——第四章:生成器(generator)

时间:2023-11-29 18:44:06浏览次数:38  
标签:__ generator Python 生成器 yield next lst print

生成器(generator):
    生成器的本质就是迭代器

    创建生成器的两种方案:
        1. 生成器函数
        2. 生成器表达式

    生成器函数
        生成器函数中有一个关键字yield
        生成器函数执行的时候, 并不会执行函数, 得到的是生成器.

        yield: 只要函数中出现了yield. 它就是一个生成器函数
            作用:
                1. 可以返回数据
                2. 可以分段的执行函数中的内容, 通过__next__()可以执行到下一个yield位置
        优势:
            用好了, 特别的节省内存


    生成器表达式 -> 一次性的
        语法: (数据 for循环 if)

 


正常的函数调用如下:

def func():
    print(123456)
    return 999

ret = func()
print(ret)

#运行结果
123456
999

使用生成器命令yield替代return。生成器函数执行的时候,并不会执行函数,得到的是生成器。

def func():
    print(123456)
    yield 999  # yield也有返回的意思.

ret = func()
print(ret)

#运行结果
<generator object func at 0x115f2dbd0>

生成器的本质就是迭代器,因此我们可以用迭代器的模式使用它:

def func():
    print(123456)
    yield 999  # yield也有返回的意思.

ret = func()
print(ret.__next__())  # yield只有执行到next的时候才会返回数据

#运行结果
123456
999

上面运行结果中:123456是函数的正常执行,999是yield返回的值,也就是说999是print()打印出来的,我们把print()拿掉就可以看到只有123456了

def func():
    print(123456)
    yield 999  # yield也有返回的意思.

ret = func()
ret.__next__()
#运行结果
123456

因此我们可以发现,yieldreturn是有一些区别的:return的用法是立即执行函数,并返回数据,而yield是只有执行到next的时候,才会返回数据。

如果我们执行2次next()又会出现和迭代器一样的StopIteration报错

def func():
    print(123456)
    yield 999  # yield也有返回的意思.

ret = func()

print(ret.__next__())  # yield只有执行到next的时候才会返回数据
print(ret.__next__())  # StopIteration

#运行结果
123456
999
Traceback (most recent call last):
  File "D:\迭代器.py", line 8, in <module>
    print(ret.__next__())  # StopIteration
          ^^^^^^^^^^^^^^
StopIteration

这也证明了:" 生成器的本质就是迭代器"

 

yield可以让程序分段的执行函数中的内容, 通过__next__()可以执行到下一个yield位置

执行一次:

def func():
    print(123)
    yield 666
    print(456)
    yield 999

ret = func()
print(ret.__next__())

#运行结果
123
666

执行两次:

def func():
    print(123)
    yield 666
    print(456)
    yield 999

ret = func()
print(ret.__next__())
print(ret.__next__())

#运行结果
123
666
456
999

这里yield就明显区别与return:当使用return的时候(比如return 666),return后面的内容全部都不会再执行。

去工厂定制10000件衣服

def order():
    lst = []
    for i in range(10000):
        lst.append(f"衣服{i}")
    return lst

lst = order()
print(lst)

简单的for循环会一次性生产出10000件衣服,并且出现了大列表lst[0,1,2,3,……,9999]这样会严重占用内存,并且双方都不好处理。

为此我们使用生成器玩法,让每次出货量为100件,每次执行__next__后再生产100件,这样就非常不占用内存,并且生产压力和库存压力都减少很多。

def order():
    lst = []
    for i in range(10000):
        lst.append(f"衣服{i}")
        if len(lst) == 100:
            yield lst
            # 下一次拿数据
            lst = []    #清空计数器重新计数


gen = order()
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())

还可以用一个列表去接收这些yield的值:

def order():
    lst = []
    for i in range(10000):
        lst.append(f"衣服{i}")
        if len(lst) == 100:
            yield lst
            # 下一次拿数据
            lst = []    # 清空计数器重新计数

gen = order()

# 用于追加结果的列表
result_list = []

# 逐次执行生成器并追加结果到列表中
result = next(gen)
result_list.append(result)

result = next(gen)
result_list.append(result)

result = next(gen)
result_list.append(result)

result = next(gen)
result_list.append(result)

# 打印包含所有结果的列表
print(result_list)

以下这段代码,存在的意义就是,使用生成器的yield特性,将程序分段执行,这样就可以避免庞大的数据执行时,严重占用内存的现象。

def order():
    lst = []
    for i in range(10000):
        lst.append(f"衣服{i}")
        if len(lst) == 100:
            yield lst
            # 下一次拿数据
            lst = []    # 清空计数器重新计数

gen = order()

# 使用 list() 函数接收生成器的 yield 返回值
result_list = list(gen)

在处理大型数据集或者生成器产生的数据量很大时,一次性获取所有值可能会导致内存占用较大,因为所有值都需要同时存储在内存中。在这种情况下,你可能希望逐个获取生成器的值,以减小内存压力。

如果数据量较大或者你希望逐个获取生成器的值,那么逐次调用 next(gen) 会更有优势!

这就是生成器的存在的价值。

标签:__,generator,Python,生成器,yield,next,lst,print
From: https://www.cnblogs.com/Magiclala/p/17865594.html

相关文章

  • ES6 Generator
    GeneratorGenerator函数是一个状态机,封装了多个内部状态。执行Generator函数会返回一个遍历器对象,返回的遍历器对象可以依次遍历Generator函数内部的每一个状态。函数特征:1.function关键字与函数名之间有一个星号。2.函数体内部使用yield表达式定义不同的内部状态。......
  • 聪明办法学python chap4:条件
    聪明办法学pythonchap4:条件if语句:通过缩进判断是不是在if里面ifelse:if成立else就不管了if不成立执行elsex=int(input())ifelifelse:平行依次判断:if():elif():elif():else:语法糖:(推导式)def(n):returnnif(n>=0)else-n等价于:def(n):​ ifn>=0:......
  • 软件测试/人工智能|为什么Python在人工智能时代异军突起
    简介Python作为一门动态、多范式的编程语言,在软件开发领域中占据着重要地位。但其真正的崛起来自于人工智能时代的到来。在这个信息爆炸和智能革命的时代,Python凭借其简洁易读的语法、丰富的库和框架以及强大的社区支持,成为了人工智能和机器学习领域的首选语言之一。Python的优......
  • 【Python入门教程】Python的shutil库介绍+基础函数使用(文件/目录复制、移动、删除、解
    ​前言        很多时候编过的代码过段时间就忘了,所以想用博文记录一下一些平时常用库的函数,今天跟大家分享一下python的shutil库的常用函数,包括文件复制、删除、移动等常见操作。同时为了复习之前python类的使用,所以今天的代码就用类封装起来了,大家直接看函数就行,不需......
  • python流行控制语句
    【一】流程控制语句介绍程序是由语句构成,而流程控制语句是用来控制程序中每条语句执行顺序的语句。可以通过控制语句实现更丰富的逻辑以及更强大的功能。几乎所有编程语言都有流程控制语句,功能也都基本相似。其流程控制方式有顺序结构分支结构循环结构这里最简单......
  • 聪明办法学python-task5
    条件if语句if<条件判断1>:<执行1>elif<条件判断2>:<执行2>elif<条件判断3>:<执行3>else:<执行4>条件判断从上向下匹配,当满足条件时执行对应的块内语句,后续的elif和else都不再执行。if-else推导式(python语法糖)returnnif(n>=0)else-neg:绝对值函数(在pyt......
  • python计算两个矩形的重叠_python计算两个矩形框重合百分比的实例
    如下所示:defmat_inter(box1,box2):#判断两个矩形是否相交#box=(xA,yA,xB,yB)x01,y01,x02,y02=box1x11,y11,x12,y12=box2lx=abs((x01+x02)/2-(x11+x12)/2)ly=abs((y01+y02)/2-(y11+y12)/2)sax=abs(x01......
  • python基础_05_python基础【2】
    【五】Python基础之程序与用户交互【1】什么是与用户交互交互的本质就是输入、输出用户交互就是人往计算机中input/输入数据,计算机print/输出结果【2】输入input函数用户输入一些内容,用户按下回车键后,input函数会返回用户输入的内容并且传输回来的数据均为字符串类型......
  • # 聪明办法学Python Task 3
    聪明办法学PythonChap4:条件使用布尔表达式n=1(n<0)*1#0(n>=0)*2#2判断值为Flase时在数值计算上等价于0,为True时在数值计算上等价于1多个判断ifa:passelifb:passelifc:passelse:passif推导式defabs1(n):ifn>0:returnn......
  • js和python获取1-100之间的质数
    jsfor(leti=2;i<=100;i++){letiszs=truefor(letj=2;j<i;j++){if(i%j===0){iszs=falsebreak}}if(iszs){zs.push(i)}}console.log(zs)pythonzs=[]foriinrange(2,101):iszs......