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

在这里插入图片描述

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

1. 生成器(Generators

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

1.1 语法

def my_generator():
    yield 1
    yield 2
    yield 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, 1
    while True:
        yield a
        a, 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 query
    records = 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 squares

xvec = [10, 20, 30]
yvec = [7, 5, 3]
sum(x*y for x,y in zip(xvec, yvec))     # dot product

unique_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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【完整思路模型代码】2023年第十三届APMCM亚太地区大学生数学建模竞赛C题

2023年第十三届APMCM亚太地区大学生数学建模竞赛C题【完整数据、思路、模型、代码】 C题 中国新能源电动汽车的发展趋势 该题并没有提供数据集,对所需数据进行收集整理是对题目进行求解的基础。在本题中,主要需要以下数据:新能源汽车历史销…

Python入门指南之基本概率和语法基础

文章目录 一、基本概念二、控制流三、函数四、模块五、数据结构六、面向对象的编程七、输入输出八、异常九、Python标准库关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战…

漏洞复现--万户ezoffice FileCheckTemplateEdit SQL注入

免责声明: 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

玻色量子携最新相干光量子计算机惊艳亮相2023数字经济大会

7月4日至7日,2023全球数字经济大会在北京国家会议中心成功举办。该大会共有100企业参展,上市公司超40家,展区遴选展示了一批国内外数字经济产业的重要成果及重点打造的数字经济基础设施。作为北京市光量子计算领域的唯一一家代表企业&#xf…

竞赛选题 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

全球三大网络安全威胁

网络安全IP数据云 - 免费IP地址查询 - 全球IP地址定位平台威胁日益复杂,涵盖了多个层面,从个人用户到大型企业,都面临着不同形式的网络安全威胁。以下是当前全球范围内广泛认可的三大网络安全威胁: 1. 恶意软件和病毒攻击&#x…

【实验笔记】C语言实验——降价提醒机器人

降价提醒机器人 题目: 小 T 想买一个玩具很久了,但价格有些高,他打算等便宜些再买。但天天盯着购物网站很麻烦,请你帮小 T 写一个降价提醒机器人,当玩具的当前价格比他设定的价格便宜时发出提醒。 输入格式&#xf…

给做steam游戏搬砖项目新手小白的5个警示

10分钟选完一个账号?自动选品软件一键下单功能讲解 今天,童话要向你们揭秘一个备受瞩目的项目——Steam搬砖项目。或许你们已经听闻过它的名字,但今天我要带领你们深入了解这个项目的本质,为你们揭示五个必须警惕的警示。让我们共…

第15届蓝桥杯Scratch选拔赛中级(STEMA)真题2023年10月

一、单选题 1.运行以下哪个程序后,巨嘴鸟会向下移动?( ) A. B. C. D. 2.运行以下程序后, 能看到几只河豚鱼( )? A.3 B.4 C.6 D.7 3.以下运算结果为“False”的是&#xff08…

逆向扒cocosjs安卓包教程-破解加密的js源码

本文只适用于cocosjs引擎打包的游戏apk,针对此类apk进行源码级别的逆向破解,可直接逐个破解工程内的源码部分,让游戏逻辑大白于你的面前,你可以针对js源码进行二次开发。按照我的教程破解过程中遇到什么问题,欢迎留言。 准备apk包 准备一个你确定用cocosjs打包好的apk包…

飞书如何接入ChatGPT-打造个人智能问答助手实现无障碍交流

目录 前言 环境列表 1.飞书设置 2.克隆feishu-chatgpt项目 3.配置config.yaml文件 4.运行feishu-chatgpt项目 5.安装cpolar内网穿透 6.固定公网地址 7.机器人权限配置 8.创建版本 9.创建测试企业 10. 机器人测试 总结 前言 在飞书中创建chatGPT机器人并且对话&am…

洗地机哪个牌子好?2023最新洗地机推荐真实推荐

现代科技发展速度越来越快,很多新产品的出现让我们的生活便利了很多。例如,近年来爆火的洗地机! 洗地机是集吸尘、拖地为一体的居家清洁工具,它能让地面变干净的同时,还能解放我们的双手,为我们清洁工作节省不少时间&…

10 Powershell读写xml文件

#读取配置文件,存入到xml变量中[Xml]$XmlContent Get-Content "D:\转移\主项发版\发布安装盘\V2.2\新一代云ERPV2.2安装盘_客户用\Packages\DataCenterService\MysoftVersion.config"#过滤-match模糊查找到满足条件的节点:ProductKey包含slxt…

想考教师编制专业不对口怎么办?

很多人在想要步入教师行业时,会遇到一个问题:专业不对口。这种情况可能会让你感到困惑和沮丧,但不要气馁,因为有很多方法可以让你实现自己的梦想。 可以通过提高自己的教育水平和能力来弥补专业不对口的缺陷。你可以通过参加教师资…

CVE-2023-27524:Apache Superset未授权访问漏洞复现

文章目录 ​Apache Superset 未授权访问漏洞(CVE-2023-27524)复现0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.漏洞复现 0x06 修复建议 ​Apache Superset 未授权访问漏洞(CVE-2023-27524)复现 0x01 前言 免责声明:请勿利用文…

SiP封装、合封芯片和芯片合封是一种技术吗?都是合封芯片技术?

合封芯片、芯片合封和SiP系统级封装经常被提及的概念。但它们是三种不同的技术,还是同一种技术的不同称呼?本文将帮助我们更好地理解它们的差异。 一、合封芯片与SiP系统级封装的定义 首先合封芯片和芯片合封都是一个意思 合封芯片是一种将多个芯片&a…

【2023-11-23】生成A~Z编号

生成A~Z编号 需要生成 A~Z的编号,当新的编号超过Z时,从A1开始,依次为B1 C1一直至Z1,如此循环。 最大支持字母为Z,超过后以添加数字后缀的形式标记 简单代码 默认从A开始循环 function getLimitNumber(_total) {var num 0var …

Nginx反向代理实现负载均衡+Keepalive实现高可用

目录 实现负载均衡 实现高可用 实现负载均衡 Nginx的几种负载均衡算法: 1.轮询(默认) 每个请求按照时间顺序逐一分配到下游的服务节点,如果其中某一节点故障,nginx 会自动剔除故障系统使用户使用不受影响。 2.权重…

网络层协议-IP协议

目录 基本概念IP协议格式分片与组装分片组装 网段划分特殊的IP地址IP地址的数量限制私有IP地址和公网IP地址路由 基本概念 TCP作为传输层控制协议,其保证的是数据传输的可靠性和传输效率,但TCP提供的仅仅是数据传输的策略,而真正负责数据在网…

Docker可视化管理界面工具Portainer安装

Portainer是Docker容器管理界面工具,可以直观的管理Docker。 部署也很简单: 官方安装文档地址 1、创建数据卷 docker volume create portainer_data2、下载允许容器 docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restartalways -v /v…