一、基础用法
1. 字典推导式(Dictionary Comprehension)
Python 支持使用推导式快速创建字典。
示例:
squares = {x: x**2 for x in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
示例2:
2. dict.get()
方法
使用 get()
可以避免 KeyError
,如果键不存在,则返回默认值。
示例:
person = {"name": "小明", "age": 25}
print(person.get("name", "未知")) # 小明
print(person.get("gender", "未知")) # 未知
3. setdefault()
方法
如果字典中没有该键,则添加该键并赋值;如果有,则返回现有值。
示例:
data = {"name": "小红"}
data.setdefault("age", 20)
print(data) # {'name': '小红', 'age': 20}
data.setdefault("age", 30)
print(data) # 仍然是 {'name': '小红', 'age': 20},因为 "age" 已存在
4. 使用 collections.defaultdict
defaultdict
允许给不存在的键提供默认值。
示例:
from collections import defaultdict
word_count = defaultdict(int)
words = ["apple", "banana", "apple", "orange", "banana", "apple"]
for word in words:
word_count[word] += 1
print(dict(word_count)) # {'apple': 3, 'banana': 2, 'orange': 1}
5. 通过 zip()
合并两个列表成字典
可以使用 zip()
轻松创建字典。
示例:
keys = ["name", "age", "gender"]
values = ["张三", 28, "男"]
person = dict(zip(keys, values))
print(person) # {'name': '张三', 'age': 28, 'gender': '男'}
6. 按值排序字典
可以使用 sorted()
对字典按值进行排序。
示例:
scores = {"张三": 85, "李四": 92, "王五": 78}
# 按值升序排序
sorted_scores = dict(sorted(scores.items(), key=lambda x: x[1]))
print(sorted_scores) # {'王五': 78, '张三': 85, '李四': 92}
7. dict.update()
合并字典
可以使用 update()
方法将一个字典的键值对更新到另一个字典中。
示例:
a = {"name": "小明", "age": 25}
b = {"age": 26, "gender": "男"}
a.update(b)
print(a) # {'name': '小明', 'age': 26, 'gender': '男'}
8. 反转字典键值对
示例:
original = {"a": 1, "b": 2, "c": 3}
reversed_dict = {v: k for k, v in original.items()}
print(reversed_dict) # {1: 'a', 2: 'b', 3: 'c'}
9. 合并多个字典
示例:
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
dict3 = {"d": 5}
merged = {**dict1, **dict2, **dict3} # Python 3.5+
print(merged) # {'a': 1, 'b': 3, 'c': 4, 'd': 5}
错误示例:
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
dict3 = {"d": 5}
print(**dict1)
# 报错 TypeError: 'a' is an invalid keyword argument for print()
错误原因
在 Python 里,**
是字典解包运算符,它的作用是把字典的键值对解包为关键字参数。print
函数的参数是用来指定要打印的内容,它期望的是位置参数或者关键字参数,而 print(**dict1)
尝试把 dict1
的键值对作为关键字参数传递给 print
函数,然而 print
函数并没有定义像 "a"
和 "b"
这样的关键字参数,所以会引发 TypeError
10. 统计字符串中每个字符出现的次数
示例:
from collections import Counter
text = "hello world"
char_count = dict(Counter(text))
print(char_count)
# {'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1}
二、示例
1. 计算嵌套字典中的最大值
场景:给定多个学生的不同科目成绩,找出每个学生的最高分数。
students_scores = {
"张三": {"数学": 78, "英语": 85, "物理": 92},
"李四": {"数学": 60, "英语": 75, "物理": 58},
"王五": {"数学": 95, "英语": 88, "物理": 91},
"赵六": {"数学": 45, "英语": 50, "物理": 55}
}
max_scores = {student: max(scores.values()) for student, scores in students_scores.items()}
print(max_scores)
# {'张三': 92, '李四': 75, '王五': 95, '赵六': 55}
2. 从嵌套字典中提取特定键
场景:从包含用户信息的字典中提取所有用户的邮箱地址。
users = {
1001: {"name": "张三", "email": "zhangsan@example.com", "age": 28},
1002: {"name": "李四", "email": "lisi@example.com", "age": 32},
1003: {"name": "王五", "email": "wangwu@example.com", "age": 24}
}
emails = {user_id: info["email"] for user_id, info in users.items()}
print(emails)
# {1001: 'zhangsan@example.com', 1002: 'lisi@example.com', 1003: 'wangwu@example.com'}
3. 计算字典中的 Top-N 最大值
场景:给定商品销售额,找出销量最高的前 3 个商品。
import heapq
sales = {
"商品A": 500,
"商品B": 1200,
"商品C": 800,
"商品D": 1500,
"商品E": 950
}
top_3 = heapq.nlargest(3, sales, key=sales.get)
print(top_3)
# ['商品D', '商品B', '商品E']
4. 统计嵌套列表中的元素频率
场景:有多个班级的学生名单,统计每个学生的出现次数。
from collections import Counter
classes = {
"班级A": ["张三", "李四", "王五"],
"班级B": ["王五", "赵六", "张三"],
"班级C": ["李四", "王五", "王五"]
}
all_students = [student for students in classes.values() for student in students]
student_counts = Counter(all_students)
print(student_counts)
# Counter({'王五': 4, '张三': 2, '李四': 2, '赵六': 1})
5. 反转字典并合并重复键
场景:将键值对字典反转,但如果多个键具有相同的值,则合并这些键。
from collections import defaultdict
original = {"a": 1, "b": 2, "c": 1, "d": 3, "e": 2}
reversed_dict = defaultdict(list)
for key, value in original.items():
reversed_dict[value].append(key)
print(dict(reversed_dict))
# {1: ['a', 'c'], 2: ['b', 'e'], 3: ['d']}
6. 按多个条件对字典排序
场景:按商品销量降序排序,若销量相同则按价格升序排序。
products = {
"商品A": {"销量": 500, "价格": 50},
"商品B": {"销量": 1200, "价格": 30},
"商品C": {"销量": 800, "价格": 20},
"商品D": {"销量": 1500, "价格": 45},
"商品E": {"销量": 1200, "价格": 35}
}
sorted_products = sorted(products.items(), key=lambda x: (-x[1]["销量"], x[1]["价格"]))
print(sorted_products)
# [('商品D', {'销量': 1500, '价格': 45}), ('商品B', {'销量': 1200, '价格': 30}), ('商品E', {'销量': 1200, '价格': 35}), ('商品C', {'销量': 800, '价格': 20}), ('商品A', {'销量': 500, '价格': 50})]
7. 递归展平嵌套字典
场景:将多层嵌套字典转换为扁平化结构。
def flatten_dict(d, parent_key='', sep='_'):
flat_dict = {}
for k, v in d.items():
new_key = f"{parent_key}{sep}{k}" if parent_key else k
if isinstance(v, dict):
flat_dict.update(flatten_dict(v, new_key, sep))
else:
flat_dict[new_key] = v
return flat_dict
nested = {
"用户": {
"张三": {"邮箱": "zhangsan@example.com", "年龄": 28},
"李四": {"邮箱": "lisi@example.com", "年龄": 32}
}
}
flattened = flatten_dict(nested)
print(flattened)
# {'用户_张三_邮箱': 'zhangsan@example.com', '用户_张三_年龄': 28, '用户_李四_邮箱': 'lisi@example.com', '用户_李四_年龄': 32}
8. 从字典中删除多个键
场景:删除字典中的多个键。
data = {"name": "张三", "age": 25, "gender": "男", "city": "北京"}
keys_to_remove = {"age", "city"}
filtered_data = {k: v for k, v in data.items() if k not in keys_to_remove}
print(filtered_data)
# {'name': '张三', 'gender': '男'}
9. 统计字典的层级
场景:计算嵌套字典的最大深度。
def dict_depth(d):
if isinstance(d, dict):
return 1 + (max(map(dict_depth, d.values())) if d else 0)
return 0
nested_dict = {
"a": {
"b": {
"c": {
"d": 42
}
}
}
}
print(dict_depth(nested_dict)) # 4
10. 使用 functools.lru_cache
进行字典缓存
场景:使用缓存提高对大字典的访问速度。
from functools import lru_cache
data = {i: i**2 for i in range(100000)} # 假设是一个大数据字典
@lru_cache(maxsize=128)
def get_value(key):
return data.get(key, "不存在")
print(get_value(99999)) # 9999800001
print(get_value(100000)) # 不存在
11. 字典按多个条件排序(综合排序)
场景:
有一个包含员工信息的字典,我们希望按照以下规则对员工进行排序:
- 先按工资降序(薪资高的排在前)
- 如果薪资相同,则按年龄升序(年轻的排在前)
employees = {
"张三": {"salary": 5000, "age": 28},
"李四": {"salary": 7000, "age": 32},
"王五": {"salary": 7000, "age": 25},
"赵六": {"salary": 6000, "age": 30},
"孙七": {"salary": 5000, "age": 24}
}
# 按工资降序,如果工资相同,则按年龄升序
sorted_employees = sorted(employees.items(), key=lambda x: (-x[1]["salary"], x[1]["age"]))
# 转换回字典
sorted_dict = dict(sorted_employees)
print(sorted_dict)
输出
{
'李四': {'salary': 7000, 'age': 32},
'王五': {'salary': 7000, 'age': 25},
'赵六': {'salary': 6000, 'age': 30},
'张三': {'salary': 5000, 'age': 28},
'孙七': {'salary': 5000, 'age': 24}
}
解析:
-x[1]["salary"]
确保按工资降序排序。x[1]["age"]
在工资相同的情况下,按年龄升序排序。
12. 排序后进行查找的字典操作
场景:
我们有一组学生的考试成绩,我们要按照:
- 先按总成绩降序排序
- 如果总成绩相同,则按数学成绩降序排序
- 排序后,查找某个特定学生的排名
students = {
"张三": {"total_score": 280, "math": 90},
"李四": {"total_score": 300, "math": 95},
"王五": {"total_score": 300, "math": 92},
"赵六": {"total_score": 275, "math": 85},
"孙七": {"total_score": 280, "math": 88}
}
# 排序规则:总分降序 -> 数学分数降序
sorted_students = sorted(students.items(), key=lambda x: (-x[1]["total_score"], -x[1]["math"]))
# 转换成排名字典
ranked_students = {name: rank + 1 for rank, (name, _) in enumerate(sorted_students)}
# 查找某个学生的排名
target_student = "王五"
print(f"{target_student} 的排名是:{ranked_students.get(target_student, '未找到')}")
# 输出:王五 的排名是:2
评论区