Python技术迷

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 json

person = {"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 全部免费领