文章目录
- 1. 列表推导式:快速构造列表
- 1.1 基础用法
- 1.2 条件筛选
- 2. 字典推导式:动态构建字典
- 2.1 基础用法
- 2.2 使用条件过滤
- 3. 集合推导式:有效去重与数据筛选
- 3.1 基本语法与应用
- 3.2 去重和转换
- 3.2 使用条件过滤
- 4. 生成器推导式:节约内存的迭代器
- 4.1 基础语法和解释
- 4.2 为什么不是“元组推导式”
Python的推导式是一种强大的数据结构生成工具,它不仅能提升代码的可读性,还能在很大程度上优化性能。本文将详细介绍四种主要的推导式——列表推导式、字典推导式、集合推导式和生成器推导式。
1. 列表推导式:快速构造列表
1.1 基础用法
列表推导式是最常用的推导式类型之一,它提供了一种非常简洁的方式来创建列表。
这种形式非常适合用来替代简单的循环语句。例如,生成一个包含0到9每个数字平方的列表:
# 列表推导式基本语法: [element for element in iterable if condition]
squares = [x**2 for x in range(10)]
print(squares)
# 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
上述代码中,x**2
是列表中的新元素,x in range(10)
遍历0到9,x**2
对每个x计算平方。这比传统的for循环更加直观和简洁。
1.2 条件筛选
列表推导式可以包含条件表达式,用于筛选符合条件的元素。例如,从列表中选出所有偶数:
numbers = range(20)
evens = [x for x in numbers if x % 2 == 0]
print(evens)
# 输出: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
这里,if x % 2 == 0
是一个条件判断,只有当x
为偶数时,它才会被加入到新的列表中。
2. 字典推导式:动态构建字典
2.1 基础用法
字典推导式可以快速地从一组键值对生成字典,是处理键值数据时非常有用的工具。
例如,将两个列表转化为一个字典,其中一个列表作为键,另一个列表作为值:
# 基本语法:{key_expression: value_expression for item in iterable if condition}
keys = ["name", "age", "gender"]
values = ["Alice", 28, "female"]
info_dict = {keys[i]: values[i] for i in range(len(keys))}
print(info_dict)
# 输出: {'name': 'Alice', 'age': 28, 'gender': 'female'}
这个例子中,range(len(keys))
生成索引序列,用来同时从keys
和values
取值。
2.2 使用条件过滤
字典推导式同样可以包含条件表达式。例如,过滤掉某些不符合条件的元素:
scores = {"Alice": 88, "Bob": 59, "Cathy": 97}
passed = {name: score for name, score in scores.items() if score >= 60}
print(passed)
# 输出: {'Alice': 88, 'Cathy': 97}
这里,if score >= 60
确保只有分数达到60分以上的学生才会被包含在新的字典中。
3. 集合推导式:有效去重与数据筛选
集合推导式是一种构建集合的简洁方式,非常适合于去除列表或其他可迭代对象中的重复元素。集合(Set)是一个无序的不包含重复元素的数据结构,因此它是实现元素唯一性的理想选择。
3.1 基本语法与应用
集合推导式的基本语法:{expression for item in iterable if condition}
这里的expression
是根据迭代的item
计算得到的表达式,iterable
是一个序列、集合或任何迭代器,而condition
是一个可选的条件表达式,用于筛选满足条件的项。
3.2 去重和转换
假设你有一个包含多个重复数字的列表,你想去除重复项,并将每个数字增加1:
numbers = [1, 2, 2, 3, 4, 4, 4, 5]
unique_numbers = {x + 1 for x in numbers}
print(unique_numbers)
# 输出: {2, 3, 4, 5, 6}
在这个例子中,表达式x + 1
确保了集合中每个元素都是原始元素加一的结果,而集合的自然属性保证了所有元素的唯一性。
3.2 使用条件过滤
集合推导式可以结合条件表达式,使其更加强大。例如,筛选大于3的元素,只保留这些元素的平方:
numbers = [1, 2, 2, 3, 4, 4, 4, 5]
filtered_squares = {x**2 for x in numbers if x > 3}
print(filtered_squares)
# 输出: {16, 25}
这里,条件if x > 3
用于筛选出大于3的元素,表达式x**2
则对筛选后的元素进行平方运算。
4. 生成器推导式:节约内存的迭代器
4.1 基础语法和解释
在Python中,术语“生成器推导式”(Generator Comprehensions)经常使人误以为会生成一个元组,因为它在语法上看起来与列表推导式非常相似,只是使用圆括号代替方括号。实际上,这种表达式生成的是一个生成器对象,而不是元组,这就是为什么它被称为生成器推导式而不是元组推导式。
生成器对象
生成器是一种迭代器,它支持延迟执行(惰性求值),只在需要时才生成或计算下一个值。这种特性使生成器非常适合处理大型数据集或复杂计算,因为它们不需要在内存中同时存储所有项。
语法和行为
生成器推导式的基本语法:(expression for item in iterable if condition)
这与列表推导式非常相似,但生成器推导式返回的是一个生成器对象。这意味着计算值的过程是按需进行的(惰性的),而不是立即计算出所有值。
4.2 为什么不是“元组推导式”
元组是不可变的数据结构,一旦创建就不能更改。如果Python支持所谓的“元组推导式”,按照推导式的定义,它将一次性计算所有值并将它们存储在元组中,这与生成器的按需生成和低内存消耗的特性完全相反。
实际上,当使用看似元组推导式的语法时(使用圆括号),Python解释器实际上是创建了一个生成器对象。
# 生成器推导式:(expression for item in iterable if condition)
squares = (x**2 for x in range(10))# 使用生成器
for square in squares:print(square)
# 这将按需打印每个数的平方,而不是一次性计算所有平方。
如果尝试使用类似推导式的语法来创建元组,例如通过将生成器推导式直接转换为元组,可以使用以下方法:
# 将生成器推导式的结果转换为元组
squares_tuple = tuple(x**2 for x in range(10))
print(squares_tuple)
# 输出: (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
总结来说,没有所谓的“元组推导式”,因为生成器推导式的设计初衷是为了按需生成值,减少内存消耗,而不是一次性构建一个完整的不可变序列。这种设计选择反映了Python在提供灵活而高效数据处理工具方面的一贯原则。
推荐: python 错误记录
参考:Comprehensions and Generator Expression in Python