python 中的生成器

image.png

目录

  • 生成器示例
      • 基本生成器示例
      • 无限序列生成器
      • 使用生成器表达式
      • 实用示例:按行读取大文件
      • 生成器的 `send`、`throw` 和 `close` 方法
  • 生成器和迭代器
      • 迭代器(Iterator)
        • 定义
        • 创建
        • 使用
        • 示例
      • 生成器(Generator)
        • 定义
        • 创建
        • 使用
        • 示例
      • 主要区别和联系
        • 1. 创建方式
        • 2. 代码简洁性
        • 3. 内存效率
        • 4. 使用方式
      • 示例对比
        • 迭代器示例
        • 生成器示例
      • 总结
  • 生成器和列表
      • 1. 定义和存储
      • 2. 内存使用
      • 3. 访问方式
      • 4. 惰性求值(Lazy Evaluation)
      • 5. 可复用性
      • 6. 示例对比
        • 序列示例
        • 生成器示例
      • 总结
  • 生成器的应用总结

在 Python 中,生成器(Generator)是一种特殊类型的迭代器,允许你在迭代过程中逐步生成值,而不是一次性生成所有值。生成器的创建通常通过包含 yield 关键字的函数实现。当函数包含 yield 时,该函数会返回一个生成器对象。
image.png

生成器的主要优点包括:

  1. 延迟求值(Lazy Evaluation):生成器在需要值的时候才生成值,这样可以节省内存。
  2. 流式处理(Stream Processing):适用于处理大型数据集或无限序列,因为它们不会将所有值一次性加载到内存中。
  3. 简洁的代码:生成器可以使代码更简洁和可读,特别是处理复杂迭代逻辑时。
    image.png

生成器示例

下面是一些使用生成器的示例:

image.png

基本生成器示例

一个简单的生成器函数,它生成从 0 到 n 的数字:

def simple_generator(n):for i in range(n):yield igen = simple_generator(5)
for value in gen:print(value)

输出:

0
1
2
3
4

无限序列生成器

生成器可以用于创建无限序列,例如生成斐波那契数列:

def fibonacci():a, b = 0, 1while True:yield aa, b = b, a + bfib_gen = fibonacci()
for _ in range(10):print(next(fib_gen))

输出:

0
1
1
2
3
5
8
13
21
34

使用生成器表达式

生成器表达式是生成器的简洁形式,类似于列表解析(List Comprehensions),但它们使用圆括号 () 而不是方括号 []。例如:

gen_exp = (x * x for x in range(10))
for value in gen_exp:print(value)

输出:

0
1
4
9
16
25
36
49
64
81

实用示例:按行读取大文件

生成器可以用于按行读取大文件而不占用过多内存:

def read_large_file(file_path):with open(file_path, 'r') as file:while line := file.readline():yield line.strip()file_gen = read_large_file('large_file.txt')
for line in file_gen:print(line)

生成器的 sendthrowclose 方法

image.png

生成器对象有三个额外的方法:

  • send(value):恢复生成器,并向生成器提供一个值,该值会成为生成器中 yield 表达式的返回值。
  • throw(type, value=None, traceback=None):在生成器中抛出一个异常。
  • close():停止生成器。

示例:

def generator_with_send():while True:value = (yield)print(f'Received: {value}')gen = generator_with_send()
next(gen)  # 预激生成器
gen.send('Hello')
gen.send('World')
gen.close()

输出:

Received: Hello
Received: World

使用生成器可以编写高效、易读的代码,特别是在处理需要逐步生成数据的场景时。

生成器和迭代器

image.png

生成器和迭代器在 Python 中都是用于迭代的对象,但它们之间有一些显著的区别和联系。下面是生成器和迭代器的详细比较:

迭代器(Iterator)

定义
  • 迭代器是一个实现了 __iter__()__next__() 方法的对象。
  • 任何实现了这些方法的对象都可以用于迭代。
创建
  • 迭代器通常通过实现这两个方法来创建。
  • 也可以使用内置的 iter() 函数从一个可迭代对象(如列表或元组)创建迭代器。
使用
  • 通过 next() 函数获取下一个元素。
  • 当没有更多元素时,next() 会抛出 StopIteration 异常。
示例
# 创建一个迭代器
class MyIterator:def __init__(self, start, end):self.current = startself.end = enddef __iter__(self):return selfdef __next__(self):if self.current >= self.end:raise StopIterationelse:self.current += 1return self.current - 1it = MyIterator(1, 5)
for num in it:print(num)# 使用内置的 iter() 函数
lst = [1, 2, 3, 4]
it = iter(lst)
print(next(it))  # 输出: 1
print(next(it))  # 输出: 2

生成器(Generator)

定义
  • 生成器是一个特殊的迭代器,通过函数来定义,使用 yield 关键字生成值。
  • 每次调用生成器函数时,生成器函数返回一个生成器对象,这个对象实现了迭代器协议。
创建
  • 通过包含 yield 关键字的函数创建。
  • 生成器表达式也可以用于创建生成器,类似于列表解析(List Comprehensions)。
使用
  • 通过 next() 函数获取下一个元素,或在 for 循环中使用。
  • 当没有更多元素时,生成器自动抛出 StopIteration 异常。
示例
# 生成器函数
def my_generator():for i in range(1, 5):yield igen = my_generator()
for num in gen:print(num)# 生成器表达式
gen_exp = (x * x for x in range(5))
for num in gen_exp:print(num)

主要区别和联系

1. 创建方式
  • 迭代器:通过实现 __iter__()__next__() 方法的类创建。
  • 生成器:通过函数定义,使用 yield 关键字。
2. 代码简洁性
  • 迭代器:创建迭代器需要定义一个类并实现两个方法。
  • 生成器:生成器函数更简洁,只需定义一个函数并使用 yield
3. 内存效率
  • 迭代器:通常用于较小的数据集合,因为它们需要预先定义数据集合。
  • 生成器:适用于大数据集合或无限数据流,因为它们是按需生成数据。
4. 使用方式
  • 迭代器:需要显式调用 next() 获取下一个元素。
  • 生成器:可以像普通函数一样调用,并在 for 循环中直接使用。

示例对比

迭代器示例
class Counter:def __init__(self, low, high):self.current = lowself.high = highdef __iter__(self):return selfdef __next__(self):if self.current > self.high:raise StopIterationelse:self.current += 1return self.current - 1counter = Counter(1, 5)
for num in counter:print(num)
生成器示例
def counter(low, high):current = lowwhile current <= high:yield currentcurrent += 1for num in counter(1, 5):print(num)

总结

  • 生成器是迭代器的一种,提供了更简洁的语法和更高的内存效率,适合处理大数据或无限序列。
  • 迭代器提供了更灵活的实现方式,适合需要自定义迭代行为的场景。

生成器和列表

image.png

生成器和序列在 Python 中有显著的区别。下面从几个方面来详细比较它们:

1. 定义和存储

  • 序列(Sequence)

    • 序列是一种容器数据类型,包含了一系列有序的元素,如列表(list)、元组(tuple)、字符串(string)等。
    • 序列中的元素是预先存储在内存中的,可以通过索引直接访问。
  • 生成器(Generator)

    • 生成器是一种特殊的迭代器,用于逐步生成元素。生成器函数使用 yield 关键字来返回一个生成器对象。
    • 生成器在运行时逐步生成元素,并不会将所有元素一次性存储在内存中。

2. 内存使用

  • 序列:由于序列会将所有元素存储在内存中,所以在处理大数据集时可能会占用大量内存。
  • 生成器:生成器按需生成元素,仅在需要时生成下一个元素,因而在处理大数据集时非常节省内存。

3. 访问方式

  • 序列:支持通过索引访问元素,并且支持切片操作。例如 lst[0]lst[1:3]
  • 生成器:不支持索引访问和切片操作。只能通过迭代器接口(如 for 循环或 next() 函数)逐个获取元素。

4. 惰性求值(Lazy Evaluation)

  • 序列:所有元素在创建时就被立即计算并存储。
  • 生成器:元素是按需计算的,只有在访问时才会生成对应的值。这种惰性求值方式可以提高效率,尤其在处理潜在的无限序列或大数据集时。

5. 可复用性

  • 序列:可以多次遍历。例如,你可以多次使用 for 循环遍历列表。
  • 生成器:只能遍历一次。一旦生成器到达末尾,再次遍历时需要重新创建生成器对象。

6. 示例对比

序列示例
# 使用列表(序列)
sequence = [1, 2, 3, 4, 5]
for item in sequence:print(item)# 可以通过索引访问
print(sequence[2])# 可以多次遍历
for item in sequence:print(item)
生成器示例
# 使用生成器
def simple_generator():for i in range(1, 6):yield igen = simple_generator()# 逐个获取生成器的值
for item in gen:print(item)# 再次遍历需要重新创建生成器
gen = simple_generator()
for item in gen:print(item)# 不能通过索引访问
try:print(gen[2])
except TypeError as e:print(e)  # 'generator' object is not subscriptable

总结

  • 序列适用于需要频繁随机访问元素和多次遍历的场景。
  • 生成器适用于处理大型数据集或无限序列,以及按需生成数据的场景。生成器在内存效率和惰性求值方面有显著优势。

生成器的应用总结

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

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

相关文章

隐私计算实训营第二期第十课:基于SPU机器学习建模实践

隐私计算实训营第二期-第十课 第十课&#xff1a;基于SPU机器学习建模实践1 隐私保护机器学习背景1.1 机器学习中隐私保护的需求1.2 PPML提供的技术解决方案 2 SPU架构2.1 SPU前端2.2 SPU编译器2.3 SPU运行时2.4 SPU目标 3 密态训练与推理3.1 四个基本问题3.2 解决数据来源问题…

全新升级!中央集中式架构功能测试为新车型保驾护航

“软件定义汽车”新时代下&#xff0c;整车电气电气架构向中央-区域集中式发展已成为行业共识&#xff0c;车型架构的变革带来更复杂的整车功能定义、更多的新技术的应用&#xff08;如SOA服务化、智能配电等&#xff09;和更短的车型研发周期&#xff0c;对整车和新产品研发的…

OkHttp的源码解读1

介绍 OkHttp 是 Square 公司开源的一款高效的 HTTP 客户端&#xff0c;用于与服务器进行 HTTP 请求和响应。它具有高效的连接池、透明的 GZIP 压缩和响应缓存等功能&#xff0c;是 Android 开发中广泛使用的网络库。 本文将详细解读 OkHttp 的源码&#xff0c;包括其主要组件…

Qt实现手动切换多种布局

引言 之前写了一个手动切换多个布局的程序&#xff0c;下面来记录一下。 程序运行效果如下&#xff1a; 示例 需求 通过点击程序界面上不同的布局按钮&#xff0c;使主工作区呈现出不同的页面布局&#xff0c;多个布局之间可以通过点击不同布局按钮切换。支持的最多的窗口…

burpsuite 设置监听窗口 火狐利用插件快速切换代理状态

一、修改burpsuite监听端口 1、首先打开burpsuite&#xff0c;点击Proxy下的Options选项&#xff1a; 2、可以看到默认的监听端口为8080&#xff0c;首先选中我们想要修改的监听&#xff0c;点击Edit进行编辑 3、将端口改为9876&#xff0c;并保存 4、可以看到监听端口修改成功…

typescript学习回顾(五)

今天来分享一下ts的泛型&#xff0c;最后来做一个练习 泛型 有时候&#xff0c;我们在书写某些函数的时候&#xff0c;会丢失一些类型信息&#xff0c;比如我下面有一个例子&#xff0c;我想提取一个数组的某个索引之前的所有数据 function getArraySomeData(newArr, n:numb…

JVM原理(十):JVM虚拟机调优分析与实战

1. 大内存硬件上的程序部署策略 这是笔者很久之前处理过的一个案例&#xff0c;但今天仍然具有代表性。一个15万PV/日左右的在线文档类型网站最近更换了硬件系统&#xff0c;服务器的硬件为四路志强处理器、16GB物理内存&#xff0c;操作系统为64位CentOS5.4&#xff0c;Resin…

阿里云centos 取消硬盘挂载并重建数据盘信息再次挂载

一、取消挂载 umount [挂载点或设备] 如果要取消挂载/dev/sdb1分区&#xff0c;可以使用以下命令&#xff1a; umount /dev/sdb1 如果要取消挂载在/mnt/mydisk的挂载点&#xff0c;可以使用以下命令&#xff1a; umount /mnt/mydisk 如果设备正忙&#xff0c;无法立即取消…

系统安全及应用(命令)

目录 一、账号安全控制 1.1 系统账号清理 1.2 密码安全控制 1.3 历史记录控制 1.4 终端自动注销 二、系统引导和登陆控制 2.1 限制su命令用户 2.2 PAM安全认证 示例一&#xff1a;通过pam 模块来防止暴力破解ssh 2.3 sudo机制提升权限 2.3.1 sudo命令&#xff08;ro…

Java的日期类常用方法

Java_Date 第一代日期类 获取当前时间 Date date new Date(); System.out.printf("当前时间" date); 格式化时间信息 SimpleDateFormat simpleDateFormat new SimpleDateFormat("yyyy-mm-dd hh:mm:ss E); System.out.printf("格式化后时间" si…

【windows|012】光猫、路由器、交换机详解

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 ​ &#x1f3c5;阿里云ACE认证高级工程师 ​ &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社…

windows USB 驱动开发-URB结构

通用串行总线 (USB) 客户端驱动程序无法直接与其设备通信。 相反&#xff0c;客户端驱动程序会创建请求并将其提交到 USB 驱动程序堆栈进行处理。 在每个请求中&#xff0c;客户端驱动程序提供一个可变长度的数据结构&#xff0c;称为 USB 请求块 (URB) &#xff0c;URB 结构描…

ctfshow-web入门-命令执行(web75-web77)

目录 1、web75 2、web76 3、web77 1、web75 使用 glob 协议绕过 open_basedir&#xff0c;读取根目录下的文件&#xff0c;payload&#xff1a; c?><?php $anew DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString(). ); } ex…

读书笔记-Java并发编程的艺术-第3章(Java内存模型)-第9节(Java内存模型综述)

3.9 Java内存模型综述 前面对Java内存模型的基础知识和内存模型的具体实现进行了说明。下面对Java内存模型的相关知识做一个总结。 3.9.1 处理器的内存模型 顺序一致性内存模型是一个理论参考模型&#xff0c;JMM和处理器内存模型在设计时通常会以顺序一致性内存模型为参照。…

C#/WPF 自制白板工具

随着电子屏幕技术的发展&#xff0c;普通的黑板已不再适用现在的教学和演示环境&#xff0c;电子白板应运而生。本篇使用WPF开发了一个电子白板工具&#xff0c;功能丰富&#xff0c;非常使用日常免费使用&#xff0c;或者进行再次开发。 示例代码如下&#xff1a; Stack<St…

拓扑排序[讲课留档]

拓扑排序 拓扑排序要解决的问题是给一个有向无环图的所有节点排序。 即在 A O E AOE AOE网中找关键路径。 前置芝士&#xff01; 有向图&#xff1a;有向图中的每一个边都是有向边&#xff0c;即其中的每一个元素都是有序二元组。在一条有向边 ( u , v ) (u,v) (u,v)中&…

ChatGPT 官方发布桌面端,向所有用户免费开放

Open AI 官方已经发布了适用于 macOS 的 ChatGPT 桌面端应用。 此前&#xff0c;该应用一直处于测试阶段&#xff0c;仅 Plus 付费订阅用户可以使用。 目前已面向所有用户开放&#xff0c;所有 Mac 用户均可免费下载使用。 我们可以访问官网下载安装包&#xff1a;https://op…

2024 年江西省研究生数学建模竞赛题目 B题投标中的竞争策略问题--完整思路、代码结果分享(仅供学习)

招投标问题是企业运营过程中必须面对的基本问题之一。现有的招投标平台有国家级的&#xff0c;也有地方性的。在招投标过程中&#xff0c;企业需要全面了解招标公告中的相关信息&#xff0c;在遵守招投标各种规范和制度的基础上&#xff0c;选择有效的竞争策略和技巧&#xff0…

基于JSP技术的校园餐厅管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果您对校园餐厅管理系统感兴趣或有相关需求&#xff0c;欢迎随时联系我。我的联系方式在文末&#xff0c;期待与您交流&#xff01; 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#x…

QT的编译过程

qmake -project 用于从源代码生成项目文件&#xff0c;qmake 用于从项目文件生成 Makefile&#xff0c;而 make 用于根据 Makefile 构建项目。 详细解释&#xff1a; qmake -project 这个命令用于从源代码目录生成一个初始的 Qt 项目文件&#xff08;.pro 文件&#xff09;。它…