Python 推导式
列表推导式
[表达式 for 变量 in 可迭代对象]
[out_exp_res for out_exp in input_list]
或者
[表达式 for 变量 in 可迭代对象 if 条件]
[out_exp_res for out_exp in input_list if condition]
# 仅保留偶数
evens = [x for x in range(10) if x % 2 == 0]
# [0, 2, 4, 6, 8]
# 多条件
nums = [x for x in range(20) if x % 2 == 0 if x % 3 == 0] # 且关系
# [0, 6, 12, 18]
# if-else 三元表达式(注意位置在前)
labels = [f"偶数: {x}" if x % 2 == 0 else f"奇数: {x}" for x in range(5)]
print(labels)
# ['偶数: 0', '奇数: 1', '偶数: 2', '奇数: 3', '偶数: 4']
- 列表推导式比传统 for 循环更快(C 层优化),且内存占用通常更小。
- 过度复杂的推导式会降低可读性
集合推导式
{ expression for item in Sequence }
或
{ expression for item in Sequence if conditional }
Python 集合推导式(Set Comprehension)与列表推导式语法几乎相同,只是将方括号 [] 换成花括号 {},结果具有集合的无序、不重复、哈希存储等特性。
- 去重(最常用场景)
# 从列表中提取唯一元素(传统方法需要手动判断)
ids = [1, 2, 2, 3, 3, 3, 4]
unique_ids = {x for x in ids}
# {1, 2, 3, 4}(顺序不保证)
# 对比:如果用列表推导式,还需要再转 set,多一步
unique_ids = list(set([x for x in ids])) # 绕远路
- 条件过滤
# 提取字符串中所有唯一的元音字母(忽略大小写)
text = "Hello World, Python is Great!"
vowels = {char.lower() for char in text if char.lower() in 'aeiou'}
# {'e', 'o', 'i', 'a'}
- 嵌套数据提取
# 提取嵌套数据中的唯一 ID(常用于数据清洗)
records = [
{"name": "Alice", "tag": "vip"},
{"name": "Bob", "tag": "vip"},
{"name": "Charlie", "tag": "normal"}
]
unique_tags = {r["tag"] for r in records}
# {'vip', 'normal'}
# 两两组合去重(利用集合无序性自动消除重复对)
pairs = {(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y}
# {(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)}
- 集合只能存放可哈希(hashable)的元素,所以推导式里不能生成列表、字典
- 当你需要判断元素是否存在时,集合推导式比列表推导式快得多
字典推导式
{ key_expr: value_expr for value in collection }
或
{ key_expr: value_expr for value in collection if condition }
- 字典的键必须唯一,推导式中遇到重复键时,后出现的值会覆盖前者
# 去重并保留最后出现的值
items = [("a", 1), ("b", 2), ("a", 3), ("c", 4)]
unique_dict = {k: v for k, v in items}
# {'a': 3, 'b': 2, 'c': 4} ← 注意 'a' 的值是 3(被覆盖了)
- 条件过滤
# 过滤:只保留及格的(分数≥60)
scores = {"Alice": 85, "Bob": 45, "Charlie": 78, "David": 59}
passed = {k: v for k, v in scores.items() if v >= 60}
# {'Alice': 85, 'Charlie': 78}
# 键值互换(值必须可哈希才能作为键)
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}
# 复杂变换:名字转大写,分数加5分奖励
bonus = {k.upper(): v + 5 for k, v in scores.items() if v < 60}
# {'BOB': 50, 'DAVID': 64} ← 只给不及格的发了 bonus