当前位置: 首页 > news >正文

Effective Python 条款7 用列表推导来取代map和filter

作为Python开发者,我们经常需要对数据进行转换和过滤操作。今天我要分享一个让代码更Pythonic的技巧——使用列表推导式替代map和filter函数。这个改变看似简单,却能显著提升代码的可读性和可维护性。

一、什么是列表推导式?

列表推导式(List Comprehension)是Python中一种优雅且高效的语法结构,可以用简洁的方式从一个可迭代对象创建新的列表。

# 计算1-10的平方列表
squares = [x2 for x in range(1, 11)]
print(squares)
# 输出:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

二、列表推导式 vs map函数

  1. 可读性对比

先看一个简单的例子:将列表中的每个元素乘以2。

列表推导式实现:

numbers = [1, 2, 3, 4, 5]
doubled = [x * 2 for x in numbers]

map函数实现:

doubled = list(map(lambda x: x * 2, numbers))

对比表格:

特性列表推导式map函数
代码简洁性★★★★★★★★☆☆
可读性★★★★★★★☆☆☆
调试便利性★★★★★★★☆☆☆
学习曲线★★☆☆☆★★★★☆
  1. 性能对比

很多开发者关心性能问题,我们做个简单测试:

import timeit# 列表推导式
def test_list_comprehension():return [x2 for x in range(1000)]# map函数
def test_map():return list(map(lambda x: x2, range(1000)))print(timeit.timeit(test_list_comprehension, number=10000))
print(timeit.timeit(test_map, number=10000))

在我的测试环境中(Python 3.9),结果如下:

  • 列表推导式:约1.2秒
  • map函数:约1.5秒

可以看到,列表推导式在性能上也有轻微优势!

三、列表推导式 vs filter函数

列表推导式更强大的地方在于它可以轻松实现过滤功能。

  1. 过滤偶数示例

列表推导式实现:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = [x for x in numbers if x % 2 == 0]

filter函数实现:

even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
  1. 复杂过滤转换示例

假设我们需要:过滤出偶数,然后计算平方

列表推导式:

result = [x2 for x in numbers if x % 2 == 0]

map+filter组合:

result = list(map(lambda x: x2, filter(lambda x: x % 2 == 0, numbers)))

对比表格:

特性列表推导式map+filter组合
代码行数1行1行(但更长)
可读性直观需要嵌套理解
执行效率相当相当
支持多重条件需要多个filter

四、高级用法:字典和集合推导式

推导式的概念不仅限于列表,Python还支持字典和集合推导式。

  1. 字典推导式
# 键值交换
original = {'a': 1, 'b': 2, 'c': 3}
inverted = {v: k for k, v in original.items()}
print(inverted)  # 输出:{1: 'a', 2: 'b', 3: 'c'}# 创建字典
squares_dict = {x: x2 for x in range(5)}
print(squares_dict)  # 输出:{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
  1. 集合推导式
# 去重并转换
words = ['hello', 'world', 'python']
lengths = {len(word) for word in words}
print(lengths)  # 输出:{5, 6}

五、什么时候该用map/filter?

虽然列表推导式在大多数情况下是更好的选择,但在某些特定场景下,map和filter可能更合适:

  1. 已有命名函数:

    def process(x):return x * 2 + 1result = list(map(process, numbers))
    
  2. 处理超大数据集(惰性求值优势):

    # 不会立即计算所有结果
    big_data = map(process, very_large_iterable)
    
  3. 函数式编程风格:

    from functools import reduce
    result = reduce(lambda x, y: x+y, map(lambda x: x*2, filter(lambda x: x>5, numbers)))
    

六、性能优化建议

  1. 大数据集处理:

    • 列表推导式会立即创建整个列表
    • map/filter返回迭代器,内存效率更高
  2. 多层循环优化:

    # 不好的写法
    result = [x*y for x in range(100) for y in range(100)]# 更好的写法(使用生成器表达式)
    result = (x*y for x in range(100) for y in range(100))
    

七、总结

通过本文的对比分析,我们可以得出以下结论:

  1. 优先使用列表推导式:在大多数情况下,它提供了更好的可读性和简洁性
  2. 合理使用map/filter:在特定场景下(已有命名函数、大数据量处理等)可以考虑使用
  3. 掌握多种推导式:字典和集合推导式同样强大

记住Python之禅的教诲:“可读性很重要”。列表推导式正是这一哲学的优秀实践,它能让你的代码更加Pythonic!

http://www.lryc.cn/news/591493.html

相关文章:

  • c++之 KMP 讲解
  • 网络原理 —— HTTP
  • 深入理解Collections.addAll方法
  • Python 离线安装 PyInstaller 的完整步骤(以python3.11.4-amd64.exe为例)
  • Trae IDE:打造完美Java开发环境的实战指南
  • 产品经理如何绘制服务蓝图(Service Blueprint)
  • 基于5G系统的打孔LDPC编码和均匀量化NMS译码算法matlab性能仿真
  • Oracle 成本优化器(CBO)与数据库统计信息:核心原理与实践
  • 线程(三) linux 同步
  • .NET Framework版本信息获取(ASP.NET探针),获取系统的.NET Framework版本
  • pycharm提交项目到github及问题解决
  • ubuntu基础搭建
  • 【Android代码】绘本翻页时通过AI识别,自动通过手机/pad朗读绘本
  • 基于单片机公交车报站系统/报站器
  • 分支和循环语句
  • Kotlin集合与空值
  • 使用位运算优化 Vue.js 应用:高效状态管理技巧
  • 学习 Flutter (四):玩安卓项目实战 - 中
  • 【LeetCode 热题 100】230. 二叉搜索树中第 K 小的元素——中序遍历
  • Java全栈面试实录:从电商支付到AIGC的深度技术挑战
  • HTML常用标签汇总(精简版)
  • Easy ARM2132
  • 测试学习之——Pytest Day3
  • 【git】使用教程
  • HTTP 状态码笔记
  • element-plus——图标推荐
  • milvus向量数据库连接测试 和 集合维度不同搜索不到内容
  • 嵌入式时钟系统
  • C++ 返回值优化(Return Value Optimization, RVO)
  • c++列表初始化