引言
大家好,我是小甲鱼!
最近有粉丝问我:"鱼哥,为什么同样一个问题,我写的代码又长又慢,别人三行就搞定了?"
仔细一看,问题出在字典上。
字典(dict)是Python中最常用的数据结构,但很多人只会用dict['key']这种基础操作。今天,我把常用的15个字典技巧全教给你,保证让你的代码简洁又高效!
1. 快速创建字典
传统写法(太长了)
# 逐个赋值,麻烦!
d = {}
d['name'] = 'xiaojiaoyu'
d['age'] = 18
d['city'] = '广州'
快速写法
# 方法1:dict() 构造函数
d = dict(name='xiaojiaoyu', age=18, city='广州')
# 方法2:字典推导式(推荐)
keys = ['name', 'age', 'city']
values = ['xiaojiaoyu', 18, '广州']
d = {k: v for k, v inzip(keys, values)}
# 方法3:fromkeys() 批量创建
d = dict.fromkeys(['name', 'age', 'city'], '默认值')
小甲鱼说: 字典推导式是Python最强大的特性之一,一定要掌握!
2. 合并字典的正确姿势
旧方法(会覆盖)
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
d1.update(d2) # b被覆盖了!
新方法(Python 3.9+)
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
d3 = d1 | d2 # {'a': 1, 'b': 3, 'c': 4}
# 或者用 |= 就地修改
d1 |= d2
兼容旧版本
# 使用 {**dict1, **dict2}
d3 = {**d1, **d2}
3. 获取值的正确方式
危险写法
d = {'name': 'xiaojiaoyu'}
print(d['age']) # KeyError: 'age' 程序崩溃!
安全获取五招
d = {'name': 'xiaojiaoyu', 'age': 18}
# 方法1:get() - 最常用
print(d.get('age', 0)) # 18
print(d.get('score', 0)) # 0(默认值)
# 方法2:setdefault() - 获取并设置默认值
result = d.setdefault('city', '广州')
print(result) # 广州(如果不存在才设置)
# 方法3:collections.defaultdict
from collections import defaultdict
dd = defaultdict(list) # 不存在的key返回空列表
dd['scores'].append(100) # 直接用,不报错!
# 方法4:try-except
try:
print(d['score'])
except KeyError:
print('不存在')
# 方法5:in 判断
if'age'in d:
print(d['age'])
4. 字典推导式的进阶玩法
# 基础:交换键值对
d = {'a': 1, 'b': 2, 'c': 3}
reversed_d = {v: k for k, v in d.items()}
# {1: 'a', 2: 'b', 3: 'c'}
# 进阶:条件过滤
scores = {'tom': 85, 'jerry': 92, 'spike': 67, 'tyke': 78}
high_scorers = {k: v for k, v in scores.items() if v >= 80}
# {'tom': 85, 'jerry': 92}
# 高级:多重条件
data = {'apple': 10, 'banana': 5, 'cherry': 20, 'date': 15}
result = {k: v for k, v in data.items() iflen(k) > 5and v > 10}
# {'banana': 5... 等等,条件是 v > 10,所以是 {'cherry': 20, 'date': 15}
5. 遍历字典的高效方法
d = {'name': 'xiaojiaoyu', 'age': 18, 'city': '广州'}
# 只遍历键
for key in d:
print(key)
# 只遍历值
for value in d.values():
print(value)
# 同时遍历键值对(推荐)
for key, value in d.items():
print(f'{key}: {value}')
# enumerate 枚举
for i, (k, v) inenumerate(d.items(), 1):
print(f'{i}. {k}: {v}')
6. 统计神器:Counter
from collections import Counter
# 统计列表中元素出现次数
nums = [1, 2, 3, 1, 2, 1, 3, 1, 2]
counter = Counter(nums)
print(counter) # Counter({1: 4, 2: 3, 3: 2})
# 统计字符串
text = "hello world"
counter = Counter(text)
print(counter.most_common(3)) # [('l', 3), ('o', 2), ('h', 1)]
# 统计单词
words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple']
word_count = Counter(words)
print(word_count) # Counter({'apple': 3, 'banana': 2, 'cherry': 1})
7. 字典排序的多种方式
d = {'tom': 85, 'jerry': 92, 'spike': 67}
# 按键排序
sorted_by_key = dict(sorted(d.items()))
# {'jerry': 92, 'spike': 67, 'tom': 85}
# 按值升序排序
sorted_by_value = dict(sorted(d.items(), key=lambda x: x[1]))
# {'spike': 67, 'tom': 85, 'jerry': 92}
# 按值降序排序
sorted_by_value_desc = dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
# {'jerry': 92, 'tom': 85, 'spike': 67}
8. 字典的集合运算
d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'b': 2, 'c': 4, 'd': 5}
# 键的交集
common_keys = d1.keys() & d2.keys()
# {'b', 'c'}
# 键的并集
all_keys = d1.keys() | d2.keys()
# {'a', 'b', 'c', 'd'}
# 键的差集
only_in_d1 = d1.keys() - d2.keys()
# {'a'}
# 键的对称差集(只在其中一个出现)
xor_keys = d1.keys() ^ d2.keys()
# {'a', 'd'}
9. 一行代码实现数据分组
from itertools import groupby
# 按成绩分组
students = [
{'name': 'tom', 'score': 85},
{'name': 'jerry', 'score': 92},
{'name': 'spike', 'score': 67},
{'name': 'tyke', 'score': 67}
]
# 按分数分组
scores = [85, 92, 67, 67]
groups = {}
for student in students:
score = student['score']
if score notin groups:
groups[score] = []
groups[score].append(student['name'])
print(groups)
# {85: ['tom'], 92: ['jerry'], 67: ['spike', 'tyke']}
# 更简洁的写法
from collections import defaultdict
groups = defaultdict(list)
for s in students:
groups[s['score']].append(s['name'])
print(dict(groups))
10. 嵌套字典的优雅操作
# 创建嵌套字典
users = {
'tom': {'age': 20, 'city': '北京'},
'jerry': {'age': 25, 'city': '上海'}
}
# 使用 ChainMap 合并多个字典
from collections import ChainMap
default_settings = {'theme': 'dark', 'language': 'zh'}
user_settings = {'theme': 'light'}
merged = ChainMap(user_settings, default_settings)
print(merged['theme']) # light(优先使用前面的)
print(merged['language']) # zh(回退到后面的)
11. 字典弹出操作
d = {'a': 1, 'b': 2, 'c': 3}
# pop() - 弹出并删除
value = d.pop('b')
print(value) # 2
print(d) # {'a': 1, 'c': 3}
# popitem() - 弹出最后一项(Python 3.7+)
key, value = d.popitem()
print(key, value) # c 3
# clear() - 清空字典
d.clear()
print(d) # {}
12. 字典视图对象
d = {'a': 1, 'b': 2, 'c': 3}
# keys() - 键的视图
print(d.keys()) # dict_keys(['a', 'b', 'c'])
# values() - 值的视图
print(d.values()) # dict_values([1, 2, 3])
# items() - 键值对的视图
print(d.items()) # dict_items([('a', 1), ('b', 2), ('c', 3)])
# 视图是动态的!
d['d'] = 4
print(d.keys()) # dict_keys(['a', 'b', 'c', 'd'])
13. 字典推导式做数据转换
# JSON 转 字典
import json
json_str = '{"name": "xiaojiaoyu", "age": 18}'
data = json.loads(json_str)
# 字典键值转换大小写
d = {'Name': 'Tom', 'AGE': 20}
d_lower = {k.lower(): v for k, v in d.items()}
# {'name': 'tom', 'age': 20}
# 扁平化嵌套字典
nested = {'user': {'name': 'tom', 'age': 20}}
flat = {'_'.join([k1, k2]): v for k1, v1 in nested.items() for k2 in v1}
# {'user_name': 'tom', 'user_age': 20}
14. 字典的解包操作
d = {'a': 1, 'b': 2, 'c': 3}
# ** 解包
deffunc(a, b, c):
print(a, b, c)
func(**d) # 1 2 3
# 合并解包
d1 = {'a': 1}
d2 = {'b': 2}
d3 = {**d1, **d2}
print(d3) # {'a': 1, 'b': 2}
15. 字典比较和相等判断
d1 = {'a': 1, 'b': 2}
d2 = {'b': 2, 'a': 1}
d3 = {'a': 1, 'b': 3}
# 比较内容(顺序无关)
print(d1 == d2) # True!
print(d1 == d3) # False
# 比较键
print(d1.keys() == d2.keys()) # True
总结
今天学习了Python字典的15个高级技巧:
- 1. 快速创建 - dict()、推导式、fromkeys()
- 2. 合并字典 - | 运算符(Python 3.9+)
- 3. 安全获取 - get()、setdefault()、defaultdict
- 5. 高效遍历 - items()、values()
- 7. 排序 - sorted() + lambda
- 11. 弹出操作 - pop()、popitem()
- 12. 视图对象 - keys()、values()、items()
写在最后
今日话题:你在项目中用过哪些字典的高级用法?在评论区分享一下吧!
点赞 - 让更多Python学习者看到这篇文章
收藏 - 以后遇到问题随时翻出来看
关注 - 点关注不迷路,小甲鱼带你学Python!
我们下期再见!