24/9/21 python的推导式、生成器

news/2024/9/21 20:47:55/文章来源:https://www.cnblogs.com/smartljy/p/18424486

python推导式和生成器

介绍

1. 列表推导式(List Comprehension)

列表推导式是最常见的一种推导式,它允许你用一行代码生成列表,形式如下:

new_list = [expression for item in iterable if condition]
  • expression:要添加到新列表的值,可以是简单的变量,也可以是运算结果。
  • item:来自迭代对象的每个元素。
  • iterable:任何可迭代对象(如列表、字符串、range 等)。
  • if condition:可选,用来筛选符合条件的元素。

示例:

生成一个包含平方数的列表:

squares = [x**2 for x in range(10)]
print(squares)  # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

2. 字典推导式(Dictionary Comprehension)

字典推导式与列表推导式类似,只不过它生成的是字典,格式如下:

new_dict = {key: value for item in iterable}

示例:

生成一个键为数字,值为其平方的字典:

squares_dict = {x: x**2 for x in range(5)}
print(squares_dict)  # 输出 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

3. 集合推导式(Set Comprehension)

集合推导式的语法与列表推导式类似,但生成的结果是集合。

new_set = {expression for item in iterable if condition}

示例:

生成一个不重复的平方数集合:

squares_set = {x**2 for x in range(5)}
print(squares_set)  # 输出 {0, 1, 4, 9, 16}

4. 生成器表达式(Generator Expression)

生成器表达式和列表推导式类似,但它不直接生成列表,而是返回一个生成器对象,用于惰性求值,适合处理大量数据。

gen = (x**2 for x in range(10))
print(list(gen))  # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

5. 嵌套推导式

推导式也可以嵌套,用于生成复杂的结构。

示例:

生成一个二维列表:

matrix = [[i * j for j in range(3)] for i in range(3)]
print(matrix)  # 输出 [[0, 0, 0], [0, 1, 2], [0, 2, 4]]

总结:

推导式使代码更加简洁、可读,并且在处理生成列表、字典或集合时特别高效。不过,推导式过于复杂时可能会影响代码的可读性,需谨慎使用。

1. 什么是生成器?

生成器(Generator) 是 Python 中一种特殊类型的迭代器,用于生成一系列的值。在常规的函数中,使用 return 来返回值并结束函数,而在生成器中,使用 yield 来逐次生成值,而不终止函数。生成器可以暂停函数的执行,并在下一次迭代时恢复执行,这种特性使得它适用于处理大量数据或无限数据流。

生成器的定义:

  • 生成器可以通过生成器函数创建,使用 yield 语句。
  • 生成器也可以通过生成器表达式创建,类似于列表推导式,但使用圆括号代替方括号。

生成器函数示例:

def my_generator():yield 1yield 2yield 3gen = my_generator()
for value in gen:print(value)

2. 生成器与列表的区别

  • 内存占用

    • 生成器是惰性求值的,这意味着它们不会一次性把所有的值加载到内存中,而是每次需要时才生成下一个值,因此非常节省内存。
    • 列表则会在创建时一次性将所有元素加载到内存中,尤其是当数据量很大时,可能导致大量的内存占用。
  • 求值方式

    • 生成器是惰性求值的(即在需要时才生成下一个值),而列表是即时求值的(一次性生成整个列表的所有值)。
  • 可重复使用

    • 生成器一旦迭代完毕,就不能再次使用,除非重新创建。
    • 列表可以多次迭代,因为它们的所有元素都存储在内存中。

列表与生成器的对比:

# 列表
lst = [x**2 for x in range(5)]
print(lst)  # 输出: [0, 1, 4, 9, 16]# 生成器
gen = (x**2 for x in range(5))
print(list(gen))  # 输出: [0, 1, 4, 9, 16]

生成器不占用大量内存,但在将生成器转换为列表时,才会将所有值存储在内存中。

3. 什么是惰性求值?

惰性求值(Lazy Evaluation),也叫延迟求值,是一种计算策略,指的是当值真正被需要时才进行计算,而不是在定义时立即计算。这使得生成器可以在处理大量数据或无限序列时显得特别高效。

惰性求值的好处:

  • 节省内存:生成器不会立即生成所有元素,只在迭代到某个值时才计算它,因此适合处理大规模或无限数据流。
  • 提高效率:通过按需生成数据,避免了不必要的计算和内存占用。

示例:

def count_up_to(n):count = 1while count <= n:yield countcount += 1counter = count_up_to(5)
print(next(counter))  # 1
print(next(counter))  # 2
# 生成器不会计算后续的值,直到你需要它们为止

在此例中,生成器在调用 next() 时才生成下一个值,未被调用时不会生成,因此更高效。

总结:

  • 生成器是惰性求值的迭代器,用来节省内存并延迟计算。
  • 列表是立即求值的,它会一次性加载所有元素。
  • 惰性求值是指在需要时才进行计算,而不是立即执行,从而提高性能和内存使用效率。

生成器特别适用于大规模或无限序列的处理场景,因为它们仅在需要时生成数据,非常节省内存。

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

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

相关文章

C#|.net core 基础 - 深拷贝的五大类N种实现方式

C#深拷贝复杂,文中介绍了五大类N种深拷贝方法,包括简单引用类型、手动方式、序列化方式、第三方库方式和扩展视野方式,并对比了性能。建议使用AutoMapper和DeepCloner等成熟库或根据性能需求选择表达式树和Emit。在实际应用中经常会有这样的需求:获取一个与原对象数据相同但…

智能写作新体验:AI写作小助手助力内容创作

在信息时代的浪潮中,内容创作已成为连接世界、传递价值的重要桥梁。然而,传统的写作方式在效率和质量上往往难以满足现代社会的需求。此时,AI写作小助手的诞生,为内容创作带来了全新的体验。本文将深入探讨AI写作小助手如何助力内容创作,开启智能写作的新篇章。AI写作小助…

基于Vue实现动态组织结构图

最近一个项目里有个前端绘制家谱图的需求,大概是下面这个样子:组件源码如下<template><table v-if="treeData.name"><tr><td :colspan="Array.isArray(treeData.children) ? treeData.children.length * 2 : 1":class="{pare…

中国能源发展报告2022

中国能源发展与未来中国能源发展报告2022林伯强高耗能产业的出路CCUS(Carbon Capture,Utilization and Storage,即碳捕获、利用与封存技术)高耗能产业布局:08 年,东高西低 >> 08 年之后,西高东低,自南向北移动,东减西增; 转移趋势北部沿海城市-河北,山东,201…

Qt表格入门

这篇博客详细介绍了Qt表格的基础知识,包括如何使用QTableWidget和QTableView来显示数据,以及如何使用QStyledItemDelegate和QSortFilterProxyModel进行数据代理、过滤和排序。此外,博客还提供了完整的代码示例,用于演示如何在Qt中创建和定制表格视图。这些内容对于Qt初学者…

王悦帆的第一次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/rjjc这个作业的目标 熟悉如何运用博客,展示自己姓名-学号 王悦帆 2022329301024一、自我介绍 (一)基本情况 大家好,我叫王悦帆,来自河南长垣,是自动化一班的成员,兴趣爱好是踢足球,看足球比赛。曾经去过现场…

day5[LangGPT结构化提示词编写实践]

任务要求:利用LangGPT优化提示词,使LLM输出正确结果。

Rebound-hackthebox

端口扫描smb探测 crackmapexec smb 10.10.11.231 -u anonymous -p "" --sharesRID 枚举 使用 CME 工具对指定主机的 SMB 服务进行扫描,并尝试使用 RID 枚举技术获取主机上的用户和组信息。RID 枚举(Relative Identifier enumeration)是一种用于获取 Windows 主机上…

CSP-J 2024 入门组初赛第一轮初赛试题及答案解析

CSP-J 2024 入门组初赛第一轮初赛试题及答案解析 一、 单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项) 1 32 位 int 类型的存储范围是( ) A -2147483647 ~ +2147483647 B -2147483647 ~ +2147483648 C -2147483648 ~ +2147483647 D -2147483648 ~ +…

数字产品护照 (DPP) 解决方案:利用 Blazor 和区块链实现产品全生命周期追踪

数字产品护照 (DPP) 解决方案:利用 Blazor 和区块链实现产品全生命周期追踪 随着全球对可持续发展和产品透明度的关注日益增加,企业需要一种可靠的方法来跟踪和管理产品生命周期中的关键数据。我们的数字产品护照(Digital Product Passport,DPP)系统正是为此而生,提供了一…

四种常用的IO模型

不管是做C端还是做B端,都要接触网络。文件操作,rpc,网上冲浪等,都与网络相关。网络又离不开IO。用的最多的IO操作就是读取和写入了。在Linux系统中,用read系统调用来发起读取操作,用write系统调用来发起写入操作。虽然在开发中,很少接触到底层的原理。但是学习后可以让我…

java学习9.21

今天回炉mybatis的用法,由于之前只是跟着教程走能成功配置数据库,但是一旦出现细小的区别就会产生自己改不了的bug,因此熟悉mybaits和其他技术的内容。知道问题出在哪里,以及怎么改。 mybatis配置 1.导入操作 (1)官网下载jar包并导入 (2)maven直接导入依赖 2.导入完之后创建…