Python 函数式编程全攻略:从理论到实战的深度解析
本文深入剖析 Python 函数式编程,详细讲解其概念、核心特性(迭代器、生成器等)、内置函数及相关模块(itertools、functools ),结合丰富示例与直观图表,助力读者全面掌握函数式编程技巧,提升编程能力与代码质量。
目录
函数式编程概念
Python 函数式编程特性
内置函数与函数式编程
itertools 模块
重点知识点扩展
(一)生成器在数据处理中的应用
(二)itertools模块在组合问题中的应用
(三)函数式编程与面向对象编程的结合
总结
函数式编程概念
函数式编程将问题分解为一系列函数,强调函数的输入输出关系,理想情况下函数无内部状态,只根据输入产生输出,避免副作用。它与过程式、声明式、面向对象编程方式不同,各有特点。多范式语言如 Python,允许在程序不同部分采用不同编程方式 。
| 编程方式 | 特点 | 示例语言 |
|---|---|---|
| 过程式 | 一连串处理输入的指令 | C、Pascal、Unix shells |
| 声明式 | 描述问题,由语言实现决定计算方式 | SQL |
| 面向对象 | 操作对象,对象有内部状态和方法 | Smalltalk、Java |
| 函数式 | 分解为函数,避免副作用 | ML 家族、Haskell |
函数式编程具有形式证明、模块化、组合性强以及易于调试和测试等优点 。虽然形式证明在实际中应用困难,但模块化使得程序更易理解和维护,组合性方便复用代码,易于调试和测试则提高了开发效率 。
Python 函数式编程特性
-
迭代器:迭代器是表示数据流的对象,支持
__next__()方法,每次返回数据流中的下一个元素,无元素时抛出StopIteration异常 。iter()函数可将可迭代对象转换为迭代器,许多内置数据类型(列表、字典、字符串等)都支持迭代 。
# 迭代器使用示例 L = [1, 2, 3] it = iter(L) print(next(it)) print(next(it)) print(next(it))
-
生成器表达式和列表推导式:生成器表达式和列表推导式借鉴自 Haskell 语言,用于对迭代器元素进行操作或筛选 。生成器表达式返回迭代器,延迟计算,适合处理大量数据或无限数据流;列表推导式返回列表 。
# 生成器表达式示例 line_list = [' line 1 \n', 'line 2 \n',' \n ', ''] stripped_iter = (line.strip() for line in line_list) # 列表推导式示例 stripped_list = [line.strip() for line in line_list]
生成器表达式和列表推导式的异同及使用场景总结:
| 比较项目 | 生成器表达式 | 列表推导式 |
|---|---|---|
| 语法 | 使用圆括号() | 使用方括号[] |
| 返回结果 | 返回一个迭代器对象,延迟计算,只有在迭代时才计算值 | 返回一个列表,立即计算并存储所有结果 |
| 内存占用 | 在处理大量数据或无限数据流时,内存占用小,因为不会一次性生成所有数据 | 处理大量数据时可能占用较多内存,因为要存储整个列表 |
| 使用场景 | 适用于处理大数据集或需要惰性求值的场景,如处理大文件、无限序列等 | 适用于需要立即获取所有结果并进行后续列表操作(如排序、索引访问)的场景 |
示例:
# 生成器表达式处理大文件,假设文件有大量行数据
with open('large_file.txt', 'r') as file:# 只在需要时逐行读取并处理,不会一次性加载所有行到内存line_lengths = (len(line) for line in file) for length in line_lengths:print(length)
# 列表推导式获取所有满足条件的数的平方,立即得到结果列表
squares = [num ** 2 for num in range(10) if num % 2 == 0]
print(squares)
-
生成器:生成器是特殊函数,包含
yield关键字,返回一个支持生成器协议的迭代器 。生成器函数执行到yield时,会暂停并保留局部变量,下次调用__next__()方法时恢复执行 。
# 生成器函数示例
def generate_ints(N):for i in range(N):yield i
gen = generate_ints(3)
print(next(gen))
print(next(gen))
print(next(gen))
生成器还支持向其传递值,通过send()方法可向生成器发送值,yield成为表达式可接收值 。此外,throw()用于在生成器内部抛出异常,close()用于结束迭代 。
# 向生成器传递值示例
def counter(maximum):i = 0while i < maximum:val = (yield i)if val is not None:i = valelse:i += 1
it = counter(10)
print(next(it))
print(next(it))
print(it.send(8))
内置函数与函数式编程
Python 的一些内置函数与函数式编程紧密相关,如map()、filter()、enumerate()、sorted()、any()、all()、zip()等 。这些函数对可迭代对象进行操作,提供了便捷的功能 。
1. map()函数:
map(f, iterA, iterB, ...) 函数会根据提供的函数f对多个可迭代对象(iterA、iterB等)的对应元素进行处理,并返回一个迭代器。例如,对列表中的每个元素进行平方操作:
nums = [1, 2, 3, 4] squared_nums = list(map(lambda x: x ** 2, nums)) print(squared_nums)
在这个例子中,map()函数将匿名函数lambda x: x ** 2应用到nums列表的每个元素上,返回一个包含平方值的迭代器,最后通过list()函数将迭代器转换为列表输出。如果有多个可迭代对象,map()会按顺序对它们的对应元素进行操作:
nums1 = [1, 2, 3] nums2 = [4, 5, 6] result = list(map(lambda x, y: x + y, nums1, nums2)) print(result)
这里map()函数将lambda x, y: x + y应用到nums1和nums2的对应元素上,实现了两个列表对应元素相加。
2. filter()函数:
filter(predicate, iter) 函数用于过滤可迭代对象中的元素。它接受一个谓词函数predicate(该函数返回布尔值)和一个可迭代对象iter,返回一个包含所有使谓词函数返回True的元素的迭代器。例如,过滤出列表中的偶数:
nums = [1, 2, 3, 4, 5, 6] even_nums = list(filter(lambda x: x % 2 == 0, nums)) print(even_nums)
在这个例子中,filter()函数使用匿名函数lambda x: x % 2 == 0筛选出nums列表中的偶数元素,并返回一个迭代器,再通过list()转换为列表。
3. enumerate()函数:
enumerate(iter, start=0) 函数用于为可迭代对象中的元素计数,返回一个包含计数(从start开始,默认为 0)和元素的元组的迭代器。在遍历列表时获取元素索引非常有用:
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):print(f'Index {index}: {fruit}')
4. sorted()函数:
sorted(iterable, key=None, reverse=False) 函数将可迭代对象中的元素收集到一个列表中进行排序,并返回排序后的列表。key参数可以指定一个函数来定制排序规则,reverse参数用于指定是否降序排序:
nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
sorted_nums = sorted(nums)
print(sorted_nums)
sorted_nums_desc = sorted(nums, reverse=True)
print(sorted_nums_desc)
# 根据元素的绝对值进行排序
nums_with_neg = [-3, 1, -4, 1, -5, 9, 2, 6, -5, 3, 5]
sorted_by_abs = sorted(nums_with_neg, key=abs)
print(sorted_by_abs)
5. any()和all()函数:
any(iter) 函数用于判断可迭代对象中是否有任何一个元素为真(在 Python 中,非零数值、非空容器等都被视为真),如果有则返回True,否则返回False。all(iter) 函数则判断可迭代对象中的所有元素是否都为真,只有所有元素都为真时才返回True:
bool_list1 = [True, False, True] bool_list2 = [False, False, False] print(any(bool_list1)) print(any(bool_list2)) print(all(bool_list1)) print(all(bool_list2))
6. zip()函数:
zip(iterA, iterB, ...) 函数从多个可迭代对象中依次选取单个元素组成元组,并返回一个包含这些元组的迭代器。当可迭代对象长度不一致时,返回的迭代器长度与最短的可迭代对象相同:
list1 = [1, 2, 3] list2 = ['a', 'b', 'c'] zipped = list(zip(list1, list2)) print(zipped)
itertools 模块
itertools模块提供了许多用于处理迭代器的函数,可分为创建新迭代器、处理迭代器元素、选取部分输出、给输出分组等几类 。
1. 创建新迭代器:count()生成无限等分数据流,cycle()无限重复可迭代对象,repeat()重复元素,chain()连接多个可迭代对象,islice()对迭代器进行切片,tee()复制迭代器 。
import itertools
# count()示例
count_iter = itertools.count(10, 5)
print(next(count_iter))
# cycle()示例
cycle_iter = itertools.cycle([1, 2, 3])
print(next(cycle_iter))
print(next(cycle_iter))
2. 其他功能函数:该模块还有如accumulate()用于计算累加值,product()计算多个可迭代对象的笛卡尔积等函数,为处理迭代器提供了更多便利 。
重点知识点扩展
(一)生成器在数据处理中的应用
在数据处理场景中,生成器可用于处理大文件,避免一次性加载大量数据到内存。例如,处理一个超大的日志文件,逐行读取并分析日志内容:
def read_log_file(file_path):with open(file_path, 'r') as file:for line in file:yield line
log_generator = read_log_file('large_log_file.log')
for line in log_generator:# 进行日志分析操作,如查找特定关键字if 'error' in line.lower():print(line)
(二)itertools模块在组合问题中的应用
在解决组合相关问题时,itertools模块的函数非常有用。比如,计算多个列表中元素的所有组合:
import itertools list1 = [1, 2] list2 = ['a', 'b'] list3 = ['x', 'y'] combinations = list(itertools.product(list1, list2, list3)) print(combinations)
(三)函数式编程与面向对象编程的结合
在实际项目中,函数式编程和面向对象编程可以结合使用。例如,在一个图形绘制系统中,图形对象可以用面向对象方式表示,而图形的变换操作可以使用函数式编程风格实现。
class Shape:def __init__(self, x, y):self.x = xself.y = y
def move_shape(shape, dx, dy):return Shape(shape.x + dx, shape.y + dy)
square = Shape(10, 10)
moved_square = move_shape(square, 5, 5)
总结
Python 的函数式编程提供了独特的编程视角和强大的工具集。通过迭代器、生成器、内置函数和itertools模块等,开发者可以编写出更简洁、高效、易维护的代码。函数式编程的优点,如模块化、组合性和易于调试测试,使其在处理复杂问题时表现出色。在实际编程中,结合函数式编程与其他编程方式,可以充分发挥 Python 的多范式特性,提升开发效率和代码质量。
-
TAG:Python、函数式编程、迭代器、生成器、itertools 模块
官方文档:Python 官方文档 - 函数式编程指引,提供了最权威和详细的知识点说明,是深入学习的重要参考。
相关文章:
Python 函数式编程全攻略:从理论到实战的深度解析
本文深入剖析 Python 函数式编程,详细讲解其概念、核心特性(迭代器、生成器等)、内置函数及相关模块(itertools、functools ),结合丰富示例与直观图表,助力读者全面掌握函数式编程技巧ÿ…...
Ollama 在 LangChain 中的使用
文章目录 一、langChain 介绍二、环境安装1.依赖库安装2.下载模型 三、基本使用示例1.使用 ChatPromptTemplate 进行对话2.流式输出3.工具调用4.多模态模型调用 四、进阶使用1.使用 ConversationChain 进行对话2.自定义提示模板3.构建一个简单的 RAG 问答系统 五、遇到问题与解…...
使用apt-rdepends制作软件离线deb安装包
使用apt-rdepends制作软件离线deb安装包 除基础软件外,还要获取软件依赖包。 依赖包工具安装 apt-get install apt-rdependsapt-rdepends工具使用 使用apt-rdepends工具,递归方式分析软件依赖,下载软件包本体,和依赖包。制作时…...
根据POD名称生成 三部曲:get、describe、log、exec
#!/bin/bash# 定义颜色变量 RED\033[0;31m GREEN\033[0;32m YELLOW\033[0;33m NC\033[0m # No Color# 检查是否传入 Pod 名称作为参数 if [ -z "$1" ]; then# 如果没有传参,则提示用户输入 Pod 名称echo -e "${YELLOW}Please enter the Pod name:${…...
SQL sever数据导入导出实验
1.创建数据库TCP-H (1)右键“数据库”,点击“新建数据库”即可 (2)用sql语言创建,此处以创建数据库DB_test为例,代码如下: use master;go--检查在当前服务器系统中的所有数据里面…...
python环境的yolov11.rknn物体检测
1.首先是我手里生成的一个yolo11的.rknn模型: 2.比对一下yolov5的模型: 2.1 yolov5模型的后期处理: outputs rknn.inference(inputs[img2], data_format[nhwc])np.save(./onnx_yolov5_0.npy, outputs[0])np.save(./onnx_yolov5_1.npy, outpu…...
I2C、SPI、UART
I2C:串口通信,同步,半双工,双线(数据线SDA时钟线SCL),最大距离1米到几米 SPI(串行外设接口):串口通信,同步,全双工,四线&…...
如何监控和优化 MySQL 中的慢 SQL
如何监控和优化 MySQL 中的慢 SQL 前言一、什么是慢 SQL?二、如何监控慢 SQL?1. 启用慢查询日志启用方法:日志内容: 2. 使用 mysqldumpslow 分析日志 三、如何分析慢 SQL?1. 使用 EXPLAIN 分析执行计划使用方法&#x…...
13-二叉树最小深度-深度优先(DFS)
一、定义 什么是二叉树的最小深度? 二叉树的最小深度是指从根节点到最近的叶子节点的最短路径上的节点数。叶子节点是指没有子节点的节点。 举个例子: 1/ \2 3/ 4 这棵树的最小深度是 2,因为从根节点 1 到叶子节点 3 的路径最短&#x…...
51单片机入门_10_数码管动态显示(数字的使用;简单动态显示;指定值的数码管动态显示)
接上篇的数码管静态显示,以下是接上篇介绍到的动态显示的原理。 动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选ÿ…...
代码补全『三重奏』:EverEdit如何用上下文识别+语法感知+智能片段重构你的编码效率!
1 代码自动完成 1.1 应用场景 在编辑文档时,为了提高编辑效率,编辑器一般都会带有自动完成功能,比如:输入括号时自动补全另一半,输入文字时,自动补全剩下的部分。 1.2 使用方法 1.2.1 自动缩进 单击主菜…...
电脑系统损坏,备份文件
一、工具准备 1.U盘:8G以上就够用,注意会格式化U盘,提前备份U盘内容 2.电脑:下载Windows系统并进行启动盘制作 二、Windows启动盘制作 1.微软官网下载启动盘制作工具微软官网下载启动盘制作工具https://www.microsoft.com/zh-c…...
Token Statistics Transformer:线性注意力革命,重新定义Transformer效率天花板
“TOKEN STATISTICS TRANSFORMER: LINEAR-TIME ATTENTION VIA VARIATIONAL RATE REDUCTION” 由Ziyang Wu等人撰写。文章提出一种新型Transformer注意力算子,通过对最大编码率降低( M C R 2 MCR^{2} MCR2)目标的变分形式进行展开优化得到&…...
Django 5实用指南(二)项目结构与管理
2.1 Django5项目结构概述 当你创建一个新的 Django 项目时,Django 会自动生成一个默认的项目结构。这个结构是根据 Django 的最佳实践来设计的,以便开发者能够清晰地管理和维护项目中的各种组件。理解并管理好这些文件和目录结构是 Django 开发的基础。…...
JAVA监听器(学习自用)
一、什么是监听器 servlet监听器是一种特殊的接口,用于监听特定的事件(如请求创建和销毁、会话创建和销毁、上下文的初始化和销毁)。 当Web应用程序中反生特定事件时,Servlet容器就会自动调用监听器中相应的方法来处理这些事件。…...
Ubuntu下mysql主从复制搭建
本文介绍mysql 8.4主从集群的搭建,从单个机器安装到集群的配置,整体走了一遍,希望对大家有帮助。mysql 8.4和之前的版本命令上有些变化,大家用来参考。 0、环境 ubuntu: 22.04mysql:8.4 1、安装mysql 1…...
VirtualBox 中使用 桥接网卡 并设置 MAC 地址
在 VirtualBox 中使用 桥接网卡 并设置 MAC 地址,可以按照以下步骤操作: 步骤 1:设置桥接网卡 打开 VirtualBox,选择你的虚拟机,点击 “设置” (Settings)。进入 “网络” (Network) 选项卡。在 “适配器 1” (Adapt…...
Ubuntu 20 掉显卡驱动的解决办法
目录 问题背景解决办法Step1:首先查看当前linux内核Step2:重启Step3:进入ubuntu advanced (即高级选项)Step4:查看有哪些linux内核Step5:如果滚回老板kernel还是没有驱动,就找到驱动…...
EasyPoi系列之框架集成及基础使用
EasyPoi系列之框架集成及基础使用 1 EasyPoi1.1 gitee仓库地址 2 EasyPoi集成至SpringBoot2.1 maven引入jar包 3 EasyPoi Excel导出3.1 基于实体对象导出3.1.1 Excel 注解3.1.2 编写实体3.1.3 编写导出方法3.1.4 导出效果 3.2 基于模板导出3.2.1 编写模板文件3.2.2 编写导出方法…...
Web后端 Tomcat服务器
一 Tomcat Web 服务器 介绍: Tomcat是一个开源的Java Servlet容器和Web服务器,由Apache软件基金会开发。它实现了Java Servlet和JavaServer Pages (JSP) 技术,用于运行Java Web应用程序。Tomcat轻量、易于配置,常作为开发和部署…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
