Python基础:生成器(Generators)和生成器表达式(Generator Expressions)详解

在这里插入图片描述

  生成器Generators)和 生成器表达式Generator Expressions)是 Python 中用于处理迭代器和序列数据的强大工具。它们允许你按需生成值,而不是一次性生成所有值,从而节省内存和提高性能。

1. 生成器(Generators

  生成器 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似于标准的函数,但当它们要返回数据时(返回一个generator iterator的函数)会使用 yield语句。 每次在生成器上调用 next() 时,它会从上次离开的位置恢复执行(它会记住上次执行语句时的所有数据值)。

1.1 语法

def my_generator():yield 1yield 2yield 3

  生成器使用函数中的yield 语句来生成值,每次调用生成器的__next__() 方法时,函数会执行到 yield,返回值并暂停,下一次调用会从上次暂停的地方继续执行。
  1)yield: 返回一个值,并暂停生成器的执行。
  2)__next__(): 获取生成器的下一个值。
  3)生成器可以使用for 循环来遍历。

1.2 应用场景

  1)处理大数据集: 生成器适合处理大量数据,因为它们一次只生成一个值,而不是一次性生成所有值。
  2)无限序列: 适用于表示无限序列,例如斐波那契数列。
  3)懒加载: 用于按需加载大文件中的数据。
  4)状态机: 生成器可以用于实现状态机,处理一系列有序事件。
  5)异步编程: 在异步编程中,生成器可以用于实现协程。

1.3 简单示例

  按照指定的模式生成一系列字符串

def pattern_generator(n):for i in range(1,n+1):yield '  A  ' * i# 使用生成器生成一系列字符串
pattern_gen = pattern_generator(5)
for pattern in pattern_gen:print(pattern)

在这里插入图片描述

1.4 应用场景示例

1.4.1 处理大数据集

"""1)处理大数据集
"""
def read_large_file(file_path):with open(file_path, 'r') as file:for line in file:yield line# 使用生成器遍历大文件
for data in read_large_file('large_data.txt'):process_data(data)

1.4.2 无限序列

"""无限序列实现斐波那契数列
"""
def fibonacci():a, b = 0, 1while True:yield aa, b = b, a + b# 使用生成器获取前 n 个斐波那契数
gen = fibonacci()
fibonacci_values = [next(gen) for _ in range(10)]
print(fibonacci_values)

1.4.3 懒加载

"""懒加载-读取数据库记录
"""
def lazy_load_records_from_database(query):# Simulating database queryrecords = query.execute()for record in records:yield record# 使用生成器按需加载数据库记录
query_result = lazy_load_records_from_database(my_query)
for record in query_result:process_record(record)

1.4.4 状态机

"""状态机
"""
def simple_state_machine():state = "start"while True:if state == "start":yield "Processing Start"state = "middle"elif state == "middle":yield "Processing Middle"state = "end"else:yield "Processing End"state = "start"# 使用生成器实现状态机
state_machine = simple_state_machine()
for _ in range(3):print(next(state_machine))

1.4.5 异步编程

"""异步编程-协程
"""
def simple_coroutine():result = yield "Start Coroutine"yield f"Received: {result}"# 使用生成器作为简单的协程
coroutine = simple_coroutine()
print(next(coroutine))  # Start Coroutine
print(coroutine.send("Data"))  # Received: Data

2. 生成器表达式(Generator Expressions)

2.1 语法

  某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,但外层为 圆括号 而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。

gen_expr = (x for x in range(5))

  与生成器类似,使用 __next__() 方法获取下一个值。
  也可以通过for 循环来遍历。

2.2 应用场景

  1)列表筛选: 生成器表达式可以用于按条件筛选列表中的元素。
  2)简单转换: 适用于对序列进行简单的转换操作。
  3)迭代: 用于按需生成值进行迭代。
  4)过滤: 通过生成器表达式筛选或过滤元素。
  5)字典生成: 用于生成字典中的值。

2.3 简单示例

  使用生成器表达式生成一个包含偶数的生成器

sum(i*i for i in range(10))                 # sum of squaresxvec = [10, 20, 30]
yvec = [7, 5, 3]
sum(x*y for x,y in zip(xvec, yvec))     # dot productunique_words = set(word for line in page  for word in line.split())valedictorian = max((student.gpa, student.name) for student in graduates)data = 'golf'
list(data[i] for i in range(len(data)-1, -1, -1))
# 生成器表达式示例:生成包含偶数的生成器
even_numbers_generator = (x for x in range(10) if x % 2 == 0)# 使用生成器迭代
for number in even_numbers_generator:print(number)

2.4 应用场景示例

2.4.1 列表筛选

"""列表筛选
"""
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# 使用生成器表达式筛选出偶数
even_numbers = (x for x in numbers if x % 2 == 0)
print(list(even_numbers))

在这里插入图片描述

2.4.2 简单转换

"""简单转换
"""
original_list = [1, 2, 3, 4, 5]# 使用生成器表达式将每个元素平方
squared_values = (x**2 for x in original_list)
print(list(squared_values))

在这里插入图片描述

2.4.3 迭代

"""迭代
"""
words = ["apple", "banana", "cherry"]# 使用生成器表达式将每个单词转换为大写
uppercase_words = (word.upper() for word in words)
print(list(uppercase_words))

在这里插入图片描述

2.4.4 过滤

"""过滤
"""
data = [10, -2, 8, -7, 4, -1]# 使用生成器表达式过滤出正数
positive_numbers = (x for x in data if x > 0)
print(list(positive_numbers))

在这里插入图片描述

2.4.5 字典生成

"""字典生成
"""
keys = ['a', 'b', 'c']
values = [1, 2, 3]# 使用生成器表达式创建字典
dictionary = {k: v for k, v in zip(keys, values)}
print(dictionary)

在这里插入图片描述

3. 生成器表达式与普通函数不同点

  返回(生成)一个迭代器对象。你无需担心显式地创建此迭代器对象,yield关键字为你做了这个工作。
  必须包含至少一个yield语句。如果需要,它可能包括多个yield关键字。
  内部实现迭代器协议(iter()next()方法)。
  自动保存局部变量及其状态。
  在yield关键字处暂停执行,并将控制权传递给调用者。
  在迭代器流没有返回值时自动引发StopIteration异常。

4. 生成器的优点

  生成器在许多方面都具有显著的优势,特别是在内存效率、延迟计算、处理无限流、易实现和可读性等方面。
  1)内存效率(逐次生成)
  生成器一次只生成一个值,而不是一次性生成所有值。这意味着在处理大量数据时,生成器可以显著节省内存,因为它们不需要在内存中存储整个序列。
  2)延迟计算(按需生成)
  生成器在需要时生成值,而不是预先生成整个序列。这种延迟计算的方式使得在处理大数据集或无限序列时能够更加高效。
  3)处理无限流(适用于无限序列)
  生成器非常适合处理无限序列,例如斐波那契数列。因为它们是按需生成的,所以可以有效地处理无限流而不会耗尽内存。
  4)易实现
  生成器的语法相对简单,只需使用 yield 关键字即可。这使得实现生成器相对容易,不需要复杂的迭代器或序列处理代码。
  5)可读性
  生成器允许将代码逻辑分解为可读的小块,每个块生成一个值。这提高了代码的可读性,尤其是在处理复杂的数据流时。

5. 参考

  官网:https://docs.python.org/zh-cn/3/tutorial/classes.html#generators
     https://docs.python.org/zh-cn/3/tutorial/classes.html#generator-expressions

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/164900.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度强化学习笔记与无线通信应用案例

这里写自定义目录标题 参考资料比较和分类基础知识16.3 有模型学习16.3.1 策略评估递归形式:Bellman 等式 16.3.2 策略改进16.3.3 策略迭代16.3.3 值迭代 16.4 免模型学习on-policy off-policy16.4.1 蒙特卡罗强化学习16.4.2 时序差分学习Sarsa算法:同策…

睡前随笔记录

一个人从出生到长大,就像一部手机从新用到旧。手机里面积累了太多的缓存,积累了太多的照片,各种app的数据,安装了各式各样的程序。 所以大概这就是年纪越大,记性越差的原因吗?就像一个屋子,堆满…

TableStructureRec: 表格结构识别推理库来了

目录 引言lineless_table_rec: 无线表格识别库安装使用结果 wired_table_rec:有线表格识别库安装使用结果 写在最后 引言 TableStructureRec 仓库是用来对文档中表格做结构化识别的推理库,包括来自 PaddleOCR 的表格结构识别算法模型、来自阿里读光有线…

新版Testwell CTC++代码覆盖率测试工具带来哪些新变化?

代码覆盖率测试工具Testwell CTC在版本10中引入了新的工具ctcreport来直接从符号和数据文件生成HTML报告。详细的特性描述可以在测试井CTC帮助中找到。在本文档中,描述了与前一代报告相比的改进和变化。 Adaptable Layout可调整布局 您可以选择一个适合于项目结构的…

scanf的返回值

总所周知,scanf是C提供的库函数的内容,而绝大多数定义的函数都会有一个返回值。 那么scanf的返回值是什么呢? 查了CPP的解释后,返回值就是返回的是scanf读取的数据的个数。 这个概念可能比较抽象。先看如下示例: 我们…

QT QJsonObject 插入 QByteArray十六进制数据

场景描述 有一组十六进制数使用QByteArray进行存储;需要将其插入QJsonObject,然后通过网络发送出去;接收到后,再转换回QByteArray; 操作代码 1. QByteArray转换QString插入QJsonObject QString str ""; …

io500 压测

目的 编译环境 centos 7.9安装包 yum groupinstall Development\ Tools yum install -y libevent-devel hwloc-devel libcephfs-devel.x86_64 编译 open mpi 下载地址 https://www.open-mpi.org/software/ompi/v5.0/编译 rpmbuild --rebuild openmpi-4.1.6-1.src.rpm安装…

Leetcode 155. 最小栈

class MinStack {//用一个辅助栈存储对应栈元素为栈顶时的最小值//当原栈插入一个元素时&#xff0c;辅助栈插入此值与当前辅助栈栈顶的值&#xff08;即插入前的最小值&#xff09;的较小值Stack<Integer> sta1;Stack<Integer> sta2;public MinStack() {sta1 new…

Redis(哨兵模式)

哨兵模式的定义&#xff1a; 是Redis的一种高可用解决方案&#xff0c;通过运行多个Redis实例来监控主从Redis实例的状态&#xff0c;当主实例出现故障时&#xff0c;哨兵会自动选举一个从实例作为新的主实例&#xff0c;从而保证系统的高可用性。哨兵模式可以监控多个主从Red…

2023亚太杯数学建模竞赛C题详细代码解析建模

C题&#xff1a;The Development Trend of New Energy Electric Vehicles in China中国谈新能源电动汽车的发展趋势 第一问部分&#xff1a; import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.prep…

Axios 通过a标签下载文件 跨域下载

<!-- a标签占位 --><a ref"down" ></a>getTest() {this.$axios.request({url: https://cnv13.55.la/download?file_key3695fa9461a0ae59cf3148581e4fe339&handle_typeexcel2pdf,method: get,responseType: blob, // 切记类型 blob}).then(re…

RC4密码(python实现)

def RC4_INIT(key):keylist(key)for i in range(len(key)):key[i]ord(key[i]) #需要将key中的每个字符转换为整数进行异或k[0 for i in range(256)]s[0 for i in range(256)]j0lengthlen(key)for i in range(256):s[i]ik[i]key[i%length] #如果key为123&#xff0c;则实际填充…

实现二叉搜索树的查找、插入和删除功能(思路+图文+代码详解)

文章目录 二叉搜索树一、搜索树1.二叉搜索树的查找2.二叉搜索树的插入3.二叉搜索树的删除4.性能分析 二叉搜索树 HashMap和HashSet的底层是一个哈希表 TreeMap 和TreeSet底层是一棵搜索树&#xff08;红黑树&#xff09; 涉及到一些搜索查找的场景可以调用Map和Set接口 一、…

Action!录屏工具免费完整版,录屏软件,打开即可解锁最新完整可用版本,支持GPU加速HDR视频录制和播放

一、软件简介 本次带来的录屏工具已升级为【完整版本】&#xff0c;所有功能全部可用。该录屏工具支持GPU硬件加速&#xff0c;可以智能识别主流硬件设备&#xff0c;支持通过GPU进行HDR视频录制和播放进行。视频录制帧率最高支持360FPS&#xff0c;直播视频帧率最高支持60FPS…

Java反射机制

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

RK3399平台开发系列讲解(内核入门篇)ConfigFS 的核心数据结构

🚀返回专栏总目录 文章目录 一、关键数据结构二、config_item 的结构体三、属性和方法沉淀、分享、成长,让自己和他人都能有所收获!😄 📢虚拟文件系统 ConfigFS 是一个特殊的文件系统,旨在提供一种动态配置 Linux 内核和设备的机制。 一、关键数据结构 ConfigFS 的核…

Vue表单的整体处理

在前端的处理中&#xff0c;表单的处理永远是占高比例的。在BOMDOMjs的时候是这样&#xff0c;在Vue的时候也是这样。Vue的表单处理做了特别的优化&#xff0c;如值绑定、数据验证、错误提示、修饰符等。 表单组件的示例&#xff1a; <script setup lang"ts">…

如何用Postman做接口自动化测试?一文5个步骤带你成功实现!

什么是自动化测试 把人对软件的测试行为转化为由机器执行测试行为的一种实践。 例如GUI自动化测试&#xff0c;模拟人去操作软件界面&#xff0c;把人从简单重复的劳动中解放出来 本质是用代码去测试另一段代码&#xff0c;属于一种软件开发工作&#xff0c;已经开发完成的用例…

解决kubernetes中微服务pod之间调用失败报错connection refused的问题

现象&#xff1a; 从这里可以看到是当前服务在调用product service服务是出现了连接拒绝connection refused 走读一下原始代码&#xff1a; 可以看到请求是由FeignClient代理发出的 &#xff0c;但问题在于为什么Feign请求的时候会产生connection refused错误&#xff1f; 上…

Programming Tensor Cores: NATIVE VOLTA TENSOR CORES WITH CUTLASS

PROGRAMMING TENSOR CORES: NATIVE VOLTA TENSOR CORES WITH CUTLASS 源自于 GTC Silicon Valley-2019: cuTENSOR: High-performance Tensor Operations in CUDA&#xff0c;介绍了 CUTLASS 1.3 中基于 Volta Tensor Core 实现高效矩阵乘法计算的策略。主要内容为以下三点&…