Python学习笔记--生成器
四、生成器
1、为什么需要生成器
通过上面的学习,可以知道列表生成式,我们可以直接创建一个列表。
但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含 1000 万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
这样就不必创建完整的 list,从而节省大量的空间。
在 Python 中,这种一边循环一边计算的机制,称为生成器:generator。
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值。并在下一次执行 next()方法时从当前位置继续运行。
那么如何创建一个生成器呢?
2、生成器的创建
最简单最简单的方法就是把一个列表生成式的 [] 改成 ()
# -*- coding: UTF-8 -*-
gen= (x * x for x in range(10))
print(gen)
输出的结果:
<generator object <genexpr> at 0x0000000002734A40>
创建 List 和 generator 的区别仅在于最外层的 [] 和 () 。
但是生成器并不真正创建数字列表, 而是返回一个生成器,这个生成器在每次计算出一个条目后,把这个条目“产生” ( yield ) 出来。
生成器表达式使用了“惰性计算” ( lazy evaluation,也有翻译为“延迟求值”,我以为这种按需调用 call by need 的方式翻译为惰性更好一些),只有在检索时才被赋值( evaluated ),所以在列表比较长的情况下使用内存上更有效。
那么竟然知道了如何创建一个生成器,那么怎么查看里面的元素呢?
3、遍历生成器的元素
按我们的思维,遍历用 for 循环,对了,我们可以试试:
# -*- coding: UTF-8 -*-
gen= (x * x for x in range(10))for num in gen :print(num)
没错,直接这样就可以遍历出来了。当然,上面也提到了迭代器,那么用 next() 可以遍历吗?当然也是可以的。
4、以函数的形式实现生成器
上面也提到,创建生成器最简单最简单的方法就是把一个列表生成式的 [] 改成 ()。为啥突然来个以函数的形式来创建呢?
其实生成器也是一种迭代器,但是你只能对其迭代一次。
这是因为它们并没有把所有的值存在内存中,而是在运行时生成值。你通过遍历来使用它们,要么用一个“for”循环,要么将它们传递给任意可以进行迭代的函数和结构。
而且实际运用中,大多数的生成器都是通过函数来实现的。那么我们该如何通过函数来创建呢?
先不急,来看下这个例子:
# -*- coding: UTF-8 -*-
def my_function():for i in range(10):print ( i )my_function()
输出的结果:
0
1
2
3
4
5
6
7
8
9
如果我们需要把它变成生成器,我们只需要把 print ( i ) 改为 yield i 就可以了,具体看下修改后的例子:
# -*- coding: UTF-8 -*-
def my_function():for i in range(10):yield iprint(my_function())
输出的结果:
<generator object my_function at 0x0000000002534A40>
但是,这个例子非常不适合使用生成器,发挥不出生成器的特点,生成器的最好的应用应该是:你不想同一时间将所有计算出来的大量结果集分配到内存当中,特别是结果集里还包含循环。因为这样会耗很大的资源。
比如下面是一个计算斐波那契数列的生成器:
# -*- coding: UTF-8 -*-
def fibon(n):a = b = 1for i in range(n):yield aa, b = b, a + b# 引用函数
for x in fibon(1000000):print(x , end = ' ')
运行的效果:

你看,运行一个这么大的参数,也不会说有卡死的状态,因为这种方式不会使用太大的资源。这里,最难理解的就是 generator 和函数的执行流程不一样。函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回。而变成 generator 的函数,在每次调用 next() 的时候执行,遇到 yield语句返回,再次执行时从上次返回的 yield 语句处继续执行。
比如这个例子:
# -*- coding: UTF-8 -*-
def odd():print ( 'step 1' )yield ( 1 )print ( 'step 2' )yield ( 3 )print ( 'step 3' )yield ( 5 )o = odd()
print( next( o ) )
print( next( o ) )
print( next( o ) )
输出的结果:
step 1
1
step 2
3
step 3
5
可以看到,odd 不是普通函数,而是 generator,在执行过程中,遇到 yield 就中断,下次又继续执行。执行 3 次 yield 后,已经没有 yield 可以执行了,如果你继续打印 print( next( o ) ) ,就会报错的。所以通常在 generator 函数中都要对错误进行捕获。
5、打印杨辉三角
通过学习了生成器,我们可以直接利用生成器的知识点来打印杨辉三角:
# -*- coding: UTF-8 -*-
def triangles( n ): # 杨辉三角形L = [1]while True:yield LL.append(0)L = [ L [ i -1 ] + L [ i ] for i in range (len(L))]n= 0
for t in triangles( 10 ): # 直接修改函数名即可运行print(t)n = n + 1if n == 10:break
输出的结果为:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
相关文章:
Python学习笔记--生成器
四、生成器 1、为什么需要生成器 通过上面的学习,可以知道列表生成式,我们可以直接创建一个列表。 但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含 1000 万个元素的列表,不仅占用很大的存储…...
【Python学习】—Python基础语法(五)
【Python学习】—Python基础语法(五) 一、循环的嵌套使用 二、九九乘法表 #外层循环表示行数 for i in range(1,10):#内层循环表示每一行的数据for j in range(1,i1):#输出每一行的内容print(f"{i} * {j} {i * j} \t",end"") #外层…...
【js】JavaScript清除所有(多个)定时器的方法:
文章目录 一、停止单个定时器二、暂停与恢复定时器三、使用Promise来管理定时器四、使用ES6特性管理定时器五、案例(定时获取页面列表数据) 一、停止单个定时器 #在某些情况下,我们可能只需要停止单个定时器。 #在JavaScript中,我…...
java实现周易64卦并返回对应的卦象(含百度百科链接)
《易经》是中华民族传统思想文化中自然哲学与人文实践的理论根源,是古代汉民族思想、智慧的结晶,被誉为“大道之源”,是古代帝王之学,政治家、军事家、商家的必修之术。 《易经》含盖万有,纲纪群伦,是中华…...
# 算法与程序的灵魂
文章目录 前言算法与程序的关系例子1:冒泡排序例子2:斐波那契数列算法优化与进阶总结 前言 大家好我是艾老虎尤,算法与程序是计算机科学中两个非常重要的概念。算法是解决问题的方法和步骤,而程序是算法的具体实现。在计算机科学…...
2023-10-21 美团2024秋招后端开发岗笔试题
1 考察dfs和拓扑排序 1.1 题目描述(如果拓扑排序不清楚可以去做一下lc 207. 课程表) 1.2 答案 import java.util.*;public class Meituan {static int m,n;public static void main(String[] args) {Scanner in new Scanner(System.in);m in.nextInt…...
汽车托运是怎样收费
汽车托运是如何收费的呢?一般来说,汽车托运的费用是会随着每公里来增加,目前的托运的每公里费用在1.2-1.8元之间,托运的距离越远那么它的托运单价费用就会越低,如果你运气好找到一家在搞活动的汽车托运公司,那么你就算…...
使用docker-compose私有化部署 GitLab
在软件开发和协作过程中,版本控制是至关重要的一环。GitLab 是一个功能强大的开源平台,提供了完整的代码管理功能,包括版本控制、问题跟踪以及持续集成等。这使得团队能够更高效地协作开发。前段时间翻阅笔记时,偶然发现了之前公司…...
Vue项目引入百度统计的正确操作步骤,亲测有效!
1、平台获取统计代码 2、在head和body中分别添加以下代码 head: <script>var _hmt _hmt || [];</script>body: <script>var _hmt _hmt || [];(function () {var hm document.createElement("script");hm.src "https://hm.baidu.com/hm.js…...
Keras中model.evaluate() 返回的是 loss value 和 metrics values
Keras官方文档: https://keras.io/models/model/#evaluate Keras中model.evaluate() 返回的是 损失值和训练时选定的指标值(例如,[AUC, , accuracy])。 训练时选定的指标值是指model.compile()里面metrics后面的值,ev…...
CSRF跨域请求伪造
1.SSRF服务端请求伪造(外网访问内网) SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF是要目标网站的内部系统。(因为他是从内部系统访问的…...
LeetCode 1465. 切割后面积最大的蛋糕:纵横分别处理
【LetMeFly】1465.切割后面积最大的蛋糕:纵横分别处理 力扣题目链接:https://leetcode.cn/problems/maximum-area-of-a-piece-of-cake-after-horizontal-and-vertical-cuts/ 矩形蛋糕的高度为 h 且宽度为 w,给你两个整数数组 horizontalCut…...
YTM32的增强型定时器eTMR外设模块详解
文章目录 eTMR外设简介eTMR工作机制系统框图引脚与信号计数器与时钟源输出比较模式PWM模式通道配对通道对的互补输出(Complementary Mode)双缓冲输出PWM(Double Switch)错误检测机制(Fault Detection) 输入…...
40.查找练习题(王道2023数据结构第7章)
试题1(王道7.2.4节综合练习5): 写出折半查找的递归算法。 #include<stdio.h> #include<stdlib.h> #include<string.h>#define MAXSIZE 10 #define ElemType int #define Status inttypedef struct{int data[MAXSIZE]; /…...
Segmentation fault 的bug解决
一,Segmentation fault 的bug解决 问题描述:自己在使用CPU上调试完代码之后,可以稳定运行,有输出结果。 但是把数据和模型加载上GPU之后,出现了报错。 Segmentation fault (core dumped) 搜了一下可能存在的原因&…...
【Python机器学习】零基础掌握BaggingRegressor集成学习
如何提升回归模型的稳定性和准确性? 在实际生活中,比如房价预测,经常会遇到一种情况:有大量的特征和样本数据,但模型的预测准确度仍然不尽人意。这时候,单一的模型(如支持向量机回归)可能表现得并不够好。 考虑到这个问题,解决方案可能是使用集成方法,特别是Baggin…...
麒麟KYLINOS通过命令行配置kysec的防火墙
原文链接:麒麟KYLINOS通过命令行配置kysec的防火墙 hello,大家好啊,今天给大家带来一篇使用命令行配置kysec的防火墙的文章,通过本篇文章的学习,大家可以了解到图形化界面中的防火墙信息是如何生成的,为后期…...
磁盘监控:告警时发送邮件
1.配置邮箱 1.编辑邮箱配置文件 vim /etc/mail.rc2.在末尾输入自己的邮箱配置,以163邮箱为例 #开启ssl set ssl-verifyignore #证书目录,下方为centos系统证书默认位置,也自行生成证书并指定 set nss-config-dir/etc/pki/nssdb # 配置的第…...
【HarmonyOS】元服务卡片router实现跳转到指定页面并传动态参数
【关键字】 元服务卡片、router跳转不同页面、传递动态参数 【写在前面】 本篇文章主要介绍开发元服务卡片时,如何实现从卡片中点击事件跳转到指定的应用内页面,并传递参数接受参数功能。此处以JS UI开发服务卡片为例,JS卡片支持组件设置ac…...
Centos安装RabbitMQ,JavaSpring发送RabbitMQ延迟延时消息,JavaSpring消费RabbitMQ消息
1,版本说明 erlang 和 rabbitmq 版本说明 https://www.rabbitmq.com/which-erlang.html 确认需要安装的mq版本以及对应的erlang版本。 2,下载安装文件 RabbitMQ下载地址: https://packagecloud.io/rabbitmq/rabbitmq-server Erlang下载地…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
