Python Dict使用小技巧
有时候……我看到有些人如此使用Python Dict。
前言
本文属于搬运内容,原作者:Kiran Maan, 原文链接。
以下技巧有助于帮助你理解如何简介的使用Python Dict,作为哈希表这是一种强大的工具,合理的使用会让代码更加简洁。
正文
我自己以前也犯过类似的错……但我从错误中吸取了教训,并加以改正。现在我来提醒你,也不要重蹈覆辙。
我不希望你重蹈我当初的覆辙。
错误一:错误地检查键是否存在
有时人们会这样检查键是否存在:
my_dict = {"name": "Kiran", "age": 24}
if "name" in my_dict:
print(my_dict["name"])
else:
print("No name found")
我知道这段代码能正常运行……但其实是多此一举。我们可以用更简洁的方式:
my_dict = {"name": "Kiran", "age": 24}
print(my_dict.get("name", "No name found"))
现在我们的代码更清晰了,不需要额外的 if-else 判断。
错误二:错误地遍历键和值
很多人会这样写循环:
my_dict = {"a": 1, "b": 2, "c": 3}
for key in my_dict:
print(key, my_dict[key])
虽然能跑,但我们有更好的方式,用 .items():
for key, value in my_dict.items():
print(key, value)
现在代码更可读,而且如果字典较大,这种方式也更高效。
错误三:错误地使用 update() 合并字典
有些新手这样合并字典:
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
dict1.update(dict2)
print(dict1)
虽然这样是可行的,但这会直接修改原始 dict1。
更好的方式是使用字典解包:
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
new_dict = {**dict1, **dict2}
print(new_dict) # {'a': 1, 'b': 3, 'c': 4}
这样我们得到了一个新的字典,不会意外修改原字典,代码更安全。
错误四:在不需要的地方使用 defaultdict
有些人过度使用 defaultdict,例如:
from collections import defaultdict
my_dict = defaultdict(int)
my_dict["a"] += 1 # 虽然能用,但真的有必要吗?
我们可以这样写,保持代码简洁:
my_dict = {}
my_dict["a"] = my_dict.get("a", 0) + 1
只有在确实需要,比如分组聚合数据时,才使用 defaultdict 才是合理的。
错误五:忽视了字典的性能问题
没错,字典很快。但当字典非常大时,性能就会下降。
比如这段代码:
my_dict = {i: i**2 for i in range(10_000_000)}
其实我们可以用生成器表达式来节省内存:
def squared_numbers():
for i in range(10_000_000):
yield i, i**2
my_dict = dict(squared_numbers())
这样内存占用更低,只有在需要时才真正生成数据。
错误六:错误地使用 setdefault()
很多新手会这样写:
data = {}
if "name" not in data:
data["name"] = "kiran"
其实更好的方式是:
data = {}
data.setdefault("name", "kiran")
这样更简洁,不需要多余的 if 判断。但有一个问题:
name = data.setdefault("name", some_expensive_function())
即使 "name" 已存在,some_expensive_function() 依然会被调用,浪费时间。
更优的做法是:
name = data.get("name", "kiran")
这样只有在键不存在时才会用默认值,避免不必要的计算。
错误七:不使用 Counter 统计计数
很多新手会手动统计,比如:
words = ["apple", "banana", "apple"]
word_count = {}
for word in words:
word_count[word] = word_count.get(word, 0) + 1
虽然这样可以,但我们有更简洁的写法:
from collections import Counter
word_count = Counter(words)
代码更干净,执行更高效。
补充Defaultdict 和 Dict的区别
✅ dict 与 defaultdict 的核心区别
🔸 dict(内置字典)
- 当访问一个不存在的键时,会 抛出 KeyError 异常。
pythonCopyEditmy_dict = {}
print(my_dict["key"]) # ❌ KeyError: 'key'
🔸 defaultdict(默认字典)
- 访问一个不存在的键时,会自动创建该键,并赋予一个默认值(由你定义的工厂函数生成)。
pythonCopyEditfrom collections import defaultdict
my_dict = defaultdict(int) # int() -> 0
print(my_dict["key"]) # ✅ 输出 0,不会报错
📌 用法对比
1. 自动初始化缺失键值(避免 if key not in dict:)
# 普通 dict
my_dict = {}
if "a" not in my_dict:
my_dict["a"] = []
my_dict["a"].append(1)
# defaultdict 简洁写法
from collections import defaultdict
my_dict = defaultdict(list)
my_dict["a"].append(1)
2. 常见工厂函数
| 工厂函数 | 默认值类型 | 示例 |
|---|---|---|
int | 0 | 计数器 |
list | [] | 分组数据 |
set | set() | 去重后分组 |
lambda: 0.0 | 自定义类型 | 浮点型初值等 |
⚠️ 注意事项
- defaultdict 会 修改原字典,自动创建新键。
- 如果不希望在访问缺失键时自动插入,应该用普通 dict + .get() 或 in 判断。
d = defaultdict(int) print("a" in dd) # False dd["a"] # 自动创建键"a" print("a" in dd) # True ✅✅ 什么时候用 defaultdict 更好?
| 场景 | 推荐用法 |
|---|---|
| 需要为缺失键赋默认值 | ✅ defaultdict |
| 需要进行分组统计 | ✅ defaultdict(list) |
想要精简代码、避免 if | ✅ defaultdict |
| 需要精细控制键是否存在 | ❌ 用 dict 更合适 |
🧠 总结
| 对比点 | dict | defaultdict |
|---|---|---|
| 缺失键访问 | 报错 KeyError | 自动创建,使用默认工厂值 |
| 需要手动初始化 | 是 | 否 |
| 推荐用途 | 控制严谨逻辑 | 分组、计数、避免冗余判断 |
如果你在写如下代码:
if key not in d:
d[key] = []
那你大概率应该改用 defaultdict。