目 录CONTENT

文章目录

Python-字典的常见高级用法及示例

~梓
2025-03-26 / 0 评论 / 1 点赞 / 15 阅读 / 0 字
温馨提示:
本文最后更新于2025-03-26,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

一、基础用法

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. 字典按多个条件排序(综合排序)

场景

有一个包含员工信息的字典,我们希望按照以下规则对员工进行排序:

  1. 先按工资降序(薪资高的排在前)
  2. 如果薪资相同,则按年龄升序(年轻的排在前)
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. 排序后进行查找的字典操作

场景

我们有一组学生的考试成绩,我们要按照:

  1. 先按总成绩降序排序
  2. 如果总成绩相同,则按数学成绩降序排序
  3. 排序后,查找某个特定学生的排名
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
1

评论区