Python中的字典是什么?
昨天下班我在地铁上无聊刷手机,突然看到一个群友问:Python 里面那个 dict 啊,到底算个啥?是不是就是个数组?我一看这个问题,脑子里就开始想,这玩意儿其实太常见了,但是要说清楚也真得花点功夫。今天正好趁午休,把我平时用字典的一些理解写下来,顺便插点代码例子,不至于空对空的讲概念。
字典到底是个啥
你先想象一下你家钥匙串,每把钥匙都有个用途:这把开大门,那把开车库,另外一把开快递柜。Python 的字典就差不多是这种关系:一堆键(key),一堆值(value),用键来找到值。它不是按顺序排的,而是通过某种算发(哈希函数)快速定位。# 创建一个简单的字典
person = {
"name": "小李",
"age": 25,
"city": "上海"
}
print(person["name"]) # 输出 小李
这里你不会去数第几个,而是直接拿 name 这把“钥匙”去开锁。
为什么不是数组
我记得我们组那个实习生小王,刚学 Python 的时候写了个循环,非要用 list 下标去存用户信息,结果查找的时候写了一堆 if else,搞得巨乱。其实用字典就干净很多,比如手机号当 key,用户信息当 value,一查就能找到,根本不需要遍历。
users = {
"13800001111": {"name": "张三", "age": 30},
"13900002222": {"name": "李四", "age": 28},
}print(users["13900002222"]["name"]) # 输出 李四
对比一下,如果用 list,你得写循环去比对手机号,效率完全不是一个级别。
字典的底层小秘密
字典之所以快,是因为用了哈希表这种结构。简单说就是:把 key 丢进一个函数,得到一个数字位置,然后把值放到这个位置去。下次你再拿相同的 key,它会走同样的路径,几乎 O(1) 时间就能取到结果。
但这里有个坑:key 必须是“可哈希”的。像 list、dict 这种可变的对象就不能做 key,因为它们随时会变,哈希值也不稳定。
# 正确
student = {"张三": 90, "李四": 85}# 错误
# test = {[1,2,3]: "error"} # 会报错:unhashable type: 'list'
所以常见的 key 类型一般是字符串、数字、元组。
常见操作
我平时写代码的时候,最常用的就是增删改查。
data = {"a": 1, "b": 2}# 增
data["c"] = 3
# 改
data["a"] = 100
# 删
del data["b"]
# 查
print(data.get("a")) # 100
print(data.get("x", "默认值")) # 默认值
特别要说一下 get,因为它不会抛异常,很多时候避免程序崩掉。
遍历的几种方式
字典遍历我踩过坑,之前写接口的时候,只拿 dict.keys(),结果后来忘记值在哪了。其实有三种常见写法:
info = {"name": "小张", "age": 22, "city": "北京"}# 遍历 key
for k in info.keys():
print(k)
# 遍历 value
for v in info.values():
print(v)
# 遍历键值对
for k, v in info.items():
print(k, v)
一般场景推荐 items(),不然你会写一堆下标取值。
字典的嵌套
我有一次写一个配置文件解析器,里面有数据库配置、日志配置啥的,全都用 dict 嵌套 dict,很清晰。
config = {
"database": {
"host": "127.0.0.1",
"port": 3306
},
"logging": {
"level": "DEBUG",
"file": "app.log"
}
}print(config["database"]["host"]) # 127.0.0.1
嵌套起来像树一样,逻辑层次清楚。
字典推导式
这个就跟列表推导式一样方便。比如我有个列表 [1,2,3],想变成一个平方表:
nums = [1, 2, 3, 4]
squares = {x: x*x for x in nums}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16}
有时候配合条件还能过滤:
even_squares = {x: x*x for x in nums if x % 2 == 0}
print(even_squares) # {2: 4, 4: 16}
字典和性能
之前线上有个小问题,日志查询接口老是卡,我们以为是数据库问题,结果后来发现是代码里用了 list 搜索。换成 dict 存索引后,性能直接飞起,接口从 3 秒缩到 0.1 秒。这个就是数据结构选型的差别。
一些常用方法
还有几个方法我觉得挺实用:
scores = {"张三": 90, "李四": 85}# pop
scores.pop("张三")
print(scores) # {"李四": 85}
# update
scores.update({"王五": 88, "赵六": 77})
print(scores)
# setdefault
print(scores.setdefault("李四", 100)) # 已存在,不变
print(scores.setdefault("小明", 60)) # 不存在,新增
print(scores)
尤其是 setdefault,用来做分组统计特别舒服。
字典和 JSON
说到实际应用,字典最常见的就是和 JSON 打交道。比如 Flask 或 Django 接口,返回的基本就是 dict 转 JSON。
import jsonperson = {"name": "小李", "age": 25}
json_str = json.dumps(person, ensure_ascii=False)
print(json_str) # {"name": "小李", "age": 25}
# JSON 转字典
data = json.loads(json_str)
print(data["name"])
你会发现 dict 和 JSON 格式几乎一一对应,这就是 Python 在做接口时这么方便的原因。
小结
写了这么多,感觉字典真的是 Python 里最万能的容器之一,日常开发几乎无处不在。从配置、缓存、数据索引,到接口交互,它都能派上用场。你要是还在用列表硬凑,真的会浪费不少性能和时间。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领