📚 今日主题:字典的高级用法与技巧
字典(dict)是 Python 中最强大、最常用的数据结构之一。今天我们来深入探讨字典的高级用法,掌握这些技巧能让你的代码更加优雅和高效。
一、字典推导式
字典推导式是创建字典的简洁方式,类似于列表推导式。
# 基础用法:创建平方字典
squares = {x: x**2 for x in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# 带条件的推导式
even_squares = {x: x**2 for x in range(1, 11) if x % 2 == 0}
print(even_squares) # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
# 从两个列表创建字典
keys = ['name', 'age', 'city']
values = ['Alice', 25, 'Beijing']
person = {k: v for k, v in zip(keys, values)}
print(person) # {'name': 'Alice', 'age': 25, 'city': 'Beijing'}
二、字典的合并与更新
Python 3.9+ 引入了更简洁的字典合并语法。
# 传统方法:update()
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
dict1.update(dict2)
print(dict1) # {'a': 1, 'b': 3, 'c': 4}
# Python 3.9+:使用 | 运算符
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged = dict1 | dict2
print(merged) # {'a': 1, 'b': 3, 'c': 4}
# 原地合并:使用 |=
dict1 |= dict2
print(dict1) # {'a': 1, 'b': 3, 'c': 4}
# 使用解包运算符(兼容旧版本)
merged = {**dict1, **dict2}
三、defaultdict:自动初始化
collections.defaultdict 可以在访问不存在的键时自动创建默认值。
from collections import defaultdict
# 统计单词出现次数
text = "python is great python is fun"
word_count = defaultdict(int)
for word in text.split():
word_count[word] += 1
print(dict(word_count))
# {'python': 2, 'is': 2, 'great': 1, 'fun': 1}
# 分组数据
students = [ ('Alice', 'A'), ('Bob', 'B'), ('Charlie', 'A'), ('David', 'C')]
grade_groups = defaultdict(list)
for name, grade in students:
grade_groups[grade].append(name)
print(dict(grade_groups))
# {'A': ['Alice', 'Charlie'], 'B': ['Bob'], 'C': ['David']}
四、Counter:计数神器
Counter 是专门用于计数的字典子类。
from collections import Counter
# 统计列表元素
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
counter = Counter(numbers)
print(counter) # Counter({4: 4, 3: 3, 2: 2, 1: 1})
# 获取最常见的元素
print(counter.most_common(2)) # [(4, 4), (3, 3)]
# 字符串计数
text = "programming"
char_counter = Counter(text)
print(char_counter.most_common(3)) # [('r', 2), ('g', 2), ('m', 2)]
# Counter 运算
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(c1 + c2) # Counter({'a': 4, 'b': 3})
print(c1 - c2) # Counter({'a': 2})
五、OrderedDict:保持插入顺序
虽然 Python 3.7+ 的普通字典已保持插入顺序,但 OrderedDict 仍有特殊用途。
from collections import OrderedDict
# 创建有序字典
ordered = OrderedDict()
ordered['first'] = 1
ordered['second'] = 2
ordered['third'] = 3
print(ordered) # OrderedDict([('first', 1), ('second', 2), ('third', 3)])
# 移动到末尾
ordered.move_to_end('first')
print(ordered) # OrderedDict([('second', 2), ('third', 3), ('first', 1)])
# 弹出第一个元素
first_item = ordered.popitem(last=False)
print(first_item) # ('second', 2)
六、字典的实用技巧
# 1. 安全获取值(避免 KeyError)
person = {'name': 'Alice', 'age': 25}
name = person.get('name', 'Unknown')
email = person.get('email', 'no@email.com')
# 2. 批量更新多个键值
person |= {'city': 'Beijing', 'job': 'Engineer'}
# 3. 字典反转(键值互换)
original = {'a': 1, 'b': 2, 'c': 3}
reversed_dict = {v: k for k, v in original.items()}
# 4. 过滤字典
filtered = {k: v for k, v in person.items() if isinstance(v, str)}
# 5. 嵌套字典访问
nested = {'user': {'profile': {'name': 'Alice'}}}
name = nested.get('user', {}).get('profile', {}).get('name', 'Unknown')
# 6. 字典解包
def greet(name, age, city):
print(f"{name}, {age}岁,来自{city}")
info = {'name': 'Bob', 'age': 30, 'city': 'Shanghai'}
greet(**info) # Bob, 30 岁,来自 Shanghai
七、实战案例:配置管理器
class ConfigManager:
"""简单的配置管理器"""
def __init__(self, defaults=None):
self._config = defaultdict(lambda: None)
if defaults:
self._config.update(defaults)
def get(self, key, default=None):
return self._config.get(key, default)
def set(self, key, value):
self._config[key] = value
def update(self, **kwargs):
self._config.update(kwargs)
def all(self):
return dict(self._config)
# 使用示例
config = ConfigManager({'debug': False, 'timeout': 30})
config.set('api_key', 'secret123')
config.update(debug=True, max_retries=3)
print(config.all())
# {'debug': True, 'timeout': 30, 'api_key': 'secret123', 'max_retries': 3}
📝 总结
今天我们学习了:
- ✅ 字典推导式的灵活用法
- ✅ 字典合并的现代语法
- ✅ defaultdict 和 Counter 的实用场景
- ✅ OrderedDict 的特殊用途
- ✅ 多个字典操作技巧
- ✅ 实战配置管理器
掌握这些字典高级用法,能让你的 Python 代码更加简洁、高效!