Python 中那些鲜为人知但实用的工具函数

Python 中一些函数像 map、filter、any、all,还有 reduce、zip 和各种 itertools 函数,都属于处理列表或其他可迭代对象的工具。它们在函数式编程中很常见,能让代码更简洁。但在日常开发中,很少用到它们,可能是因为习惯了 for 循环或列表推导式。

先说说基础的几个:map、filter、any 和 all

这些是 Python 内置的,经常用于列表或其他序列的处理。

map 函数

map 的作用是把一个函数应用到列表的每个元素上,返回一个新的迭代器。

用法示例:

python 复制代码
nums = [1, 2, 3]
squared = list(map(lambda x: x**2, nums))  # [1, 4, 9]

场景:批量转换数据,比如把数字平方或字符串转大写。

优势:代码简洁,底层高效。

用 for 循环的等价实现:

python 复制代码
squared = []
for x in nums:
    squared.append(x**2)

用列表推导式的等价实现:

python 复制代码
squared = [x**2 for x in nums]

对比分析:map 更简洁,尤其是结合 lambda 时。但列表推导式更符合 Python 风格,可读性好。for 循环最直观,但代码多。map 的优势在大数据时(延迟计算,节省内存),劣势是需要转成 list 才能看到结果。为什么少用?很多人觉得列表推导式够用,不想多学一个函数。

filter 函数

filter 用一个条件函数筛选列表,只留满足条件的元素。

用法示例:

python 复制代码
nums = [1, 2, 3, 4]
evens = list(filter(lambda x: x % 2 == 0, nums))  # [2, 4]

场景:数据过滤,比如提取偶数或非空字符串。

优势:简洁,延迟计算。

用 for 循环的等价实现:

python 复制代码
evens = []
for x in nums:
    if x % 2 == 0:
        evens.append(x)

用列表推导式的等价实现:

python 复制代码
evens = [x for x in nums if x % 2 == 0]

对比分析:filter 简短,但列表推导式更常见,可读性高。for 循环适合复杂条件。filter 的优势是函数式风格,劣势是初学者不熟。为什么少用?列表推导式太方便了,很多人直接用它。

any 函数

any 检查列表中是否有至少一个 True。

用法示例:

python 复制代码
nums = [0, 0, 1]
has_true = any(nums)  # True

场景:快速检查是否存在满足条件的元素,比如列表是否有负数。

优势:短路求值(一找到 True 就停),高效。

用 for 循环的等价实现:

python 复制代码
has_true = False
for x in nums:
    if x:
        has_true = True
        break

用列表推导式的等价实现:不太直接,通常结合 any 和生成器:

python 复制代码
has_true = any(x for x in nums)  # 但这和原函数一样

对比分析:any 最简洁,直观。for 循环显式,但代码长。列表推导式在这里不占优势。any 的劣势是需要生成器表达式。为什么少用?简单检查时,很多人直接写循环,不想用 any。

all 函数

all 检查列表中是否所有元素都是 True。

用法示例:

python 复制代码
nums = [1, 2, 3]
all_true = all(nums)  # True

场景:验证所有元素满足条件,比如所有成绩及格。

优势:短路求值,高效。

用 for 循环的等价实现:

python 复制代码
all_true = True
for x in nums:
    if not x:
        all_true = False
        break

用列表推导式的等价实现:类似 any,通常结合 all。

对比分析:all 简洁明了。for 循环可靠,但冗长。为什么少用?同 any,习惯问题。

再聊聊其他内置的:reduce、zip 和 sorted

这些也常用于迭代处理。

reduce 函数(需导入 functools)

reduce 把列表元素逐步累积计算成一个值。

用法示例:

python 复制代码
from functools import reduce
nums = [1, 2, 3, 4]
total = reduce(lambda x, y: x + y, nums)  # 10

场景:求和、乘积或合并数据。

优势:函数式,灵活。

用 for 循环的等价实现:

python 复制代码
total = 0
for x in nums:
    total += x

用列表推导式的等价实现:不适合累积,通常用 sum(nums) 代替简单求和。

对比分析:reduce 通用,但可读性差(尤其复杂函数)。for 循环清晰。reduce 的劣势是需导入,为什么少用?内置 sum/min/max 够用,reduce 显得多余。

zip 函数

zip 把多个列表配对成元组列表。

用法示例:

python 复制代码
names = ['A', 'B']
scores = [90, 85]
pairs = list(zip(names, scores))  # [('A', 90), ('B', 85)]

场景:并行遍历多个序列。

优势:简洁,延迟计算。

用 for 循环的等价实现:

python 复制代码
pairs = []
for i in range(min(len(names), len(scores))):
    pairs.append((names[i], scores[i]))

用列表推导式的等价实现:

python 复制代码
pairs = [(names[i], scores[i]) for i in range(min(len(names), len(scores)))]

对比分析:zip 最优雅。for 和推导式用索引,容易出错。zip 的劣势是长度不等时截断。为什么少用?初学者不熟,习惯用索引。

sorted 函数(带 key)

sorted 返回排序后的新列表,可自定义 key。

用法示例:

python 复制代码
words = ['cat', 'dog', 'elephant']
sorted_words = sorted(words, key=len)  # ['cat', 'dog', 'elephant']

场景:自定义排序。

优势:灵活,稳定。

用 for 循环的等价实现:不直接,需手动排序算法,如:

python 复制代码
# 简单冒泡排序
sorted_words = words[:]  # 复制
for i in range(len(sorted_words)):
    for j in range(i+1, len(sorted_words)):
        if len(sorted_words[i]) > len(sorted_words[j]):
            sorted_words[i], sorted_words[j] = sorted_words[j], sorted_words[i]

用列表推导式的等价实现:不适合排序,通常用 sorted 本身。

对比分析:sorted 高效(内置算法)。手动 for 复杂、低效。为什么少用?简单排序不需 key,很多人直接 sorted(words)。

itertools 模块里的工具

itertools 有很多迭代工具,都返回迭代器。

chain 函数

chain 把多个列表连成一个。

用法示例:

python 复制代码
from itertools import chain
list1 = [1, 2]
list2 = [3, 4]
combined = list(chain(list1, list2))  # [1, 2, 3, 4]

场景:合并数据源。

优势:高效,不复制。

用 for 循环的等价实现:

python 复制代码
combined = []
for lst in [list1, list2]:
    for x in lst:
        combined.append(x)

用列表推导式的等价实现:

python 复制代码
combined = [x for lst in [list1, list2] for x in lst]

对比分析:chain 简洁,内存好。for 和推导式直观。chain 的劣势是需导入。为什么少用?简单合并用 + 就行。

groupby 函数

groupby 把连续相同键的元素分组(需先排序)。

用法示例:

python 复制代码
from itertools import groupby
words = sorted(['cat', 'dog', 'rat'], key=len)
groups = {k: list(g) for k, g in groupby(words, key=len)}

场景:数据分组。

优势:高效。

用 for 循环的等价实现:

python 复制代码
groups = {}
current_key = None
for word in words:
    key = len(word)
    if key != current_key:
        current_key = key
        groups[key] = []
    groups[key].append(word)

用列表推导式的等价实现:不太直接,需要类似 for 的逻辑。

对比分析:groupby 简洁,但需排序。for 灵活。为什么少用?分组场景少,很多人用 pandas。

combinations 和 permutations

combinations 生成组合,permutations 生成排列。

用法示例:

python 复制代码
from itertools import combinations, permutations
items = ['A', 'B']
combs = list(combinations(items, 2))  # [('A', 'B')]
perms = list(permutations(items, 2))  # [('A', 'B'), ('B', 'A')]

场景:算法问题。

优势:高效。

用 for 循环的等价实现:嵌套循环,如 for combinations:

python 复制代码
combs = []
for i in range(len(items)):
    for j in range(i+1, len(items)):
        combs.append((items[i], items[j]))

用列表推导式的等价实现:

python 复制代码
combs = [(items[i], items[j]) for i in range(len(items)) for j in range(i+1, len(items))]

对比分析:itertools 简单。for/推导式易懂但代码长。为什么少用?排列组合不常见。

repeat 函数

repeat 重复生成值。

用法示例:

python 复制代码
from itertools import repeat
list(repeat(42, 3))  # [42, 42, 42]

场景:填充常量。

优势:简单。

用 for 循环的等价实现:

python 复制代码
vals = []
for _ in range(3):
    vals.append(42)

用列表推导式的等价实现:

python 复制代码
vals = [42 for _ in range(3)]

对比分析:repeat 短。推导式更常见。为什么少用?推导式太方便。

dropwhile 和 takewhile

dropwhile 丢弃开头直到条件假;takewhile 取开头直到条件假。

用法示例:

python 复制代码
from itertools import dropwhile, takewhile
nums = [1,3,5,2,4]
list(dropwhile(lambda x: x % 2 != 0, nums))  # [2,4]
list(takewhile(lambda x: x % 2 != 0, nums))  # [1,3,5]

场景:切分序列。

优势:条件切片。

用 for 循环的等价实现:for dropwhile:

python 复制代码
result = []
started = False
for x in nums:
    if not started and x % 2 == 0:
        started = True
    if started:
        result.append(x)

对比分析:itertools 简洁。for 显式。为什么少用?切分需求少。

zip_longest 函数

zip_longest 配对,填充短的。

用法示例:

python 复制代码
from itertools import zip_longest
list(zip_longest([1,2], ['a','b','c'], fillvalue=0))  # [(1,'a'), (2,'b'), (0,'c')]

场景:不等长配对。

优势:处理缺失。

用 for 循环的等价实现:

python 复制代码
result = []
max_len = max(len([1,2]), len(['a','b','c']))
for i in range(max_len):
    a = [1,2][i] if i < len([1,2]) else 0
    b = ['a','b','c'][i] if i < len(['a','b','c']) else 0
    result.append((a, b))

对比分析:zip_longest 方便。for 繁琐。为什么少用?长度相等时用 zip。

starmap 函数

starmap 像 map,但解包元组。

用法示例:

python 复制代码
from itertools import starmap
list(starmap(lambda x,y: x*y, [(2,3),(4,5)]))  # [6,20]

场景:多参数映射。

优势:扩展 map。

用 for 循环的等价实现:

python 复制代码
result = []
for pair in [(2,3),(4,5)]:
    result.append(pair[0] * pair[1])

用列表推导式的等价实现:

python 复制代码
result = [x*y for x,y in [(2,3),(4,5)]]

对比分析:starmap 函数式。推导式更直观。为什么少用?推导式够用。

结语

itertools中还有很多非常强大的函数,但更不常用了。虽然这些函数都是 Python 的好工具,能让代码更简洁高效,尤其大数据或函数式风格时。

为什么少用呢?我想一来是习惯吧:for 循环和列表推导式太接地气,可读性高。二是场景有限:很多函数针对特定问题,日常不遇。三是学习成本:需导入 itertools,觉得麻烦。

相关推荐
SiYuanFeng30 分钟前
Colab复现 NanoChat:从 Tokenizer(CPU)、Base Train(CPU) 到 SFT(GPU) 的完整踩坑实录
python·colab
炸炸鱼.1 小时前
Python 操作 MySQL 数据库
android·数据库·python·adb
_深海凉_2 小时前
LeetCode热题100-颜色分类
python·算法·leetcode
AC赳赳老秦2 小时前
OpenClaw email技能:批量发送邮件、自动回复,高效处理工作邮件
运维·人工智能·python·django·自动化·deepseek·openclaw
zhaoshuzhaoshu3 小时前
Python 语法之数据结构详细解析
python
AI问答工程师3 小时前
Meta Muse Spark 的"思维压缩"到底是什么?我用 Python 复现了核心思路(附代码)
人工智能·python
zfan5204 小时前
python对Excel数据处理(1)
python·excel·pandas
小饕4 小时前
我从零搭建 RAG 学到的 10 件事
python
老歌老听老掉牙4 小时前
PyQt5+Qt Designer实战:可视化设计智能参数配置界面,告别手动布局时代!
python·qt
格鸰爱童话5 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习