当前位置:首页>python>Python字典推导式——优雅地创建字典

Python字典推导式——优雅地创建字典

  • 2026-09-24 08:25:11
Python字典推导式——优雅地创建字典

一、什么是字典推导式?

字典推导式(Dictionary Comprehension) 是 Python 中一种简洁的语法,用于从可迭代对象(如列表、元组、range等)中快速创建字典。它与列表推导式类似,但生成的是字典而不是列表。

字典推导式的基本思想是:对可迭代对象中的每个元素应用一个表达式,生成键值对,从而构建新的字典。

# 传统方式:用 for 循环创建字典squares = {}for x inrange(5):    squares[x] = x**2print(squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}# 字典推导式方式squares = {x: x**2for x inrange(5)}print(squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

二、基本语法

{键表达式: 值表达式 for 变量 in 可迭代对象}
  • • 键表达式:对每个元素计算的表达式,结果将作为新字典的键。
  • • 值表达式:对每个元素计算的表达式,结果将作为新字典的值。
  • • 变量:代表可迭代对象中的每个元素的临时变量名。
  • • 可迭代对象:任何可迭代的对象(如列表、range、字符串、元组等)。

执行过程:

  1. 1. 遍历可迭代对象中的每个元素。
  2. 2. 将当前元素赋值给变量。
  3. 3. 计算键表达式和值表达式。
  4. 4. 将生成的键值对添加到新字典中。

三、基本示例

3.1 从 range 生成数字及其平方

squares = {x: x**2for x inrange(1, 6)}print(squares)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

3.2 从列表中创建字典(元素作为键)

fruits = ["苹果", "香蕉", "橙子"]# 将水果名作为键,长度作为值fruit_dict = {fruit: len(fruit) for fruit in fruits}print(fruit_dict)  # {'苹果': 2, '香蕉': 2, '橙子': 2}

3.3 使用 enumerate 生成索引映射

colors = ["红", "绿", "蓝"]# 索引作为键,颜色作为值color_dict = {index: color for index, color inenumerate(colors)}print(color_dict)  # {0: '红', 1: '绿', 2: '蓝'}

四、带条件的字典推导式

可以在字典推导式中添加 if 条件,筛选满足条件的元素。

语法:

{键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}
numbers = [1, 2, 3, 4, 5, 6]# 只保留偶数的平方even_squares = {x: x**2for x in numbers if x % 2 == 0}print(even_squares)  # {2: 4, 4: 16, 6: 36}

也可以对键和值分别应用条件(但条件只能筛选元素,不能分别筛选键和值,因为键值对是基于同一个元素生成的)。


五、从两个列表创建字典(使用 zip)

如果有两个列表,一个作为键,一个作为值,可以用 zip 将它们配对,然后用字典推导式创建字典。

keys = ["name", "age", "city"]values = ["张三", 25, "北京"]person = {keys[i]: values[i] for i inrange(len(keys))}# 更简洁的方式:person = {k: v for k, v inzip(keys, values)}print(person)  # {'name': '张三', 'age': 25, 'city': '北京'}

zip 将两个列表打包成元组对,然后解包赋值给 k, v。

如果两个列表长度不一致,zip 会按最短的截断。


六、嵌套循环的字典推导式

字典推导式中也可以使用多个 for 子句,相当于嵌套循环。

# 生成坐标点字典,键为 (x, y),值为 x*ypoints = {(x, y): x*y for x inrange(3) for y inrange(3)}print(points)# {(0, 0): 0, (0, 1): 0, (0, 2): 0, (1, 0): 0, (1, 1): 1, (1, 2): 2, (2, 0): 0, (2, 1): 2, (2, 2): 4}

等价于:

points = {}for x inrange(3):for y inrange(3):        points[(x, y)] = x*y

七、交换字典的键和值

使用字典推导式可以方便地交换键和值(前提是值是可哈希且唯一的,否则会丢失重复值)。

original = {"a": 1, "b": 2, "c": 3}swapped = {value: key for key, value in original.items()}print(swapped)  # {1: 'a', 2: 'b', 3: 'c'}

如果原值不唯一,后面的键会覆盖前面的。

original = {"a": 1, "b": 1}swapped = {value: key for key, value in original.items()}print(swapped)  # {1: 'b'}  # 只保留了最后一个

八、与 for 循环的对比

方式
代码量
可读性
性能
普通 for 循环
较多
一般
稍慢
字典推导式
一行
简洁
较快(内部 C 实现)

字典推导式通常更高效,也更 Pythonic。但过于复杂的推导式可能影响可读性,此时应使用普通循环。


九、注意事项

  1. 1. 键必须唯一:如果生成的键重复,后面的键值对会覆盖前面的。
  2. 2. 键必须可哈希:键必须是不可变类型(如整数、字符串、元组等),列表、字典等不能作为键。
  3. 3. 可读性:不要在一个推导式中塞入太多逻辑,否则难以理解。嵌套循环或复杂条件建议拆分成普通循环。
  4. 4. 作用域:推导式中的临时变量不会污染外部命名空间。
  5. 5. 与生成器表达式的区别:字典推导式直接生成完整字典,占用内存;而生成器表达式(用小括号)逐个生成,节省内存,但不能直接得到字典。

十、实战案例

案例1:统计字符串中字符出现次数

text = "hello world"# 统计每个字符(排除空格)的出现次数char_count = {ch: text.count(ch) for ch inset(text) if ch != ' '}print(char_count)  # {'h': 1, 'e': 1, 'l': 3, 'o': 2, 'w': 1, 'r': 1, 'd': 1}

注意:这里用 set(text) 去重,避免重复计算。

案例2:将列表中的单词映射为大写形式

words = ["python", "java", "c++", "javascript"]upper_dict = {word: word.upper() for word in words}print(upper_dict)  # {'python': 'PYTHON', 'java': 'JAVA', 'c++': 'C++', 'javascript': 'JAVASCRIPT'}

案例3:根据条件修改值

scores = {"小明": 85, "小红": 92, "小刚": 78}# 将及格(>=60)的分数标记为"Pass",否则为"Fail"result = {name: "Pass"if score >= 60else"Fail"for name, score in scores.items()}print(result)  # {'小明': 'Pass', '小红': 'Pass', '小刚': 'Pass'}

案例4:读取文件构建字典

假设有一个文件 data.txt 内容为:

apple 5banana 3orange 8

可以用字典推导式读取并构建字典:

withopen("data.txt") as f:    fruit_count = {line.split()[0]: int(line.split()[1]) for line in f}print(fruit_count)  # {'apple': 5, 'banana': 3, 'orange': 8}

案例5:使用字典推导式生成九九乘法表(键为元组)

multiplication = {(i, j): i*j for i inrange(1, 10) for j inrange(1, i+1)}print(multiplication)# {(1, 1): 1, (2, 1): 2, (2, 2): 4, (3, 1): 3, (3, 2): 6, (3, 3): 9, ...}

十一、总结

  • • 字典推导式 是创建字典的简洁高效方式。
  • • 基本语法:{key_expr: value_expr for item in iterable}
  • • 可添加 if 条件筛选元素。
  • • 结合 zip 可以方便地从两个列表创建字典。
  • • 嵌套循环可用于生成更复杂的键值对。
  • • 适用于交换键值、数据转换、筛选等场景。
  • • 注意保持可读性,避免过度复杂。

掌握字典推导式,能让你的代码更 Pythonic,更简洁优雅。

最新文章

随机文章