跳到主要内容 Python 常用数据结构:字典(Dictionary)详解与实战 | 极客日志
Python 算法
Python 常用数据结构:字典(Dictionary)详解与实战 Python 字典是一种基于键值对存储数据的容器类型,支持通过不可变键快速检索值。文章详细介绍了字典的创建方式(字面量、构造函数、推导式)、核心运算(成员判断、索引访问)、常用方法(get、update、pop、clear 等)以及进阶用法(嵌套字典、深浅拷贝、defaultdict)。通过字符统计、股票筛选及配置管理等实战案例,展示了字典在数据建模与分析中的应用,强调了键的不可变性原则及常见陷阱。
kaikai 发布于 2025/2/6 更新于 2026/4/20 2 浏览迄今为止,我们已经为大家介绍了 Python 中的三种容器型数据类型(列表、元组、集合),但是这些数据类型仍然不足以帮助我们解决所有的问题。例如,我们需要一个变量来保存一个人的多项信息,包括:姓名、年龄、身高、体重、家庭住址、本人手机号、紧急联系人手机号。此时你会发现,我们之前学过的列表、元组和集合类型都不够好使。
person1 = ['王大锤' , 55 , 168 , 60 , '成都市武侯区科华北路 62 号 1 栋 101' , '13122334455' , '13800998877' ]
person2 = ('王大锤' , 55 , 168 , 60 , '成都市武侯区科华北路 62 号 1 栋 101' , '13122334455' , '13800998877' )
person3 = {'王大锤' , 55 , 168 , 60 , '成都市武侯区科华北路 62 号 1 栋 101' , '13122334455' , '13800998877' }
集合肯定是最不合适的,因为集合中不能有重复元素,如果一个人的年龄和体重刚好相同,那么集合中就会少一项信息;同理,如果这个人的手机号和紧急联系人手机号是相同的,那么集合中又会少一项信息。另一方面,虽然列表和元组可以把一个人的所有信息都保存下来,但是当你想要获取这个人的手机号或家庭住址时,你得先知道他的手机号是列表或元组中的第几个元素。总之,在遇到上述的场景时,列表、元组、集合都不是最合适的选择,此时我们需要字典(dictionary)类型,这种数据类型最适合把相关联的信息组装到一起,可以帮助我们解决 Python 程序中为真实事物建模的问题。
Python 程序中的字典跟现实生活中的字典很像,它以键值对(键和值的组合)的方式把数据组织到一起,我们可以通过键找到与之对应的值并进行操作。就像《新华字典》中,每个字(键)都有与它对应的解释(值)一样,每个字和它的解释合在一起就是字典中的一个条目,而字典中通常包含了很多个这样的条目。
创建和使用字典 Python 中创建字典可以使用{}字面量语法,这一点跟上一节课讲的集合是一样的。但是字典的{}中的元素是以键值对的形式存在的,每个元素由:分隔的两个值构成,:前面是键,:后面是值,代码如下所示。
xinhua = {
'麓' : '山脚下' ,
'路' : '道,往来通行的地方;方面,地区:南~货,外~货;种类:他俩是一~人' ,
'蕗' : '甘草的别名' ,
'潞' : '潞水,水名,即今山西省的浊漳河;潞江,水名,即云南省的怒江'
}
print (xinhua)
person = {
'name' : '王大锤' ,
'age' : 55 ,
'height' : 168 ,
'weight' : 60 ,
'addr' : '成都市武侯区科华北路 62 号 1 栋 101' ,
'tel' : '13122334455' ,
'emergency_contact' : '13800998877'
}
print (person)
通过上面的代码,相信大家已经看出来了,用字典来保存一个人的信息远远优于使用列表或元组,因为我们可以用:前面的键来表示条目的含义,而:后面就是这个条目所对应的值。
当然,如果愿意,我们也可以使用内置函数dict或者是字典的生成式语法来创建字典,代码如下所示。
person = dict (name='王大锤' , age=55 , height=168 , weight=60 , addr='成都市武侯区科华北路 62 号 1 栋 101' )
print (person)
items1 = dict (zip ('ABCDE' , '12345' ))
print (items1)
items2 = dict (zip ('ABCDE' , range (1 , 10 )))
print (items2)
items3 = {x: x ** 3 for x in range (1 , 6 )}
print (items3)
想知道字典中一共有多少组键值对,仍然是使用len函数;如果想对字典进行遍历,可以用for循环,但是需要注意,for循环只是对字典的键进行了遍历,不过没关系,在学习了字典的索引运算后,我们可以通过字典的键获取到和这个键对应的值。
person = {'name' : '王大锤' , 'age' : 55 , 'height' : 168 , 'weight' : 60 , 'addr' : '成都市武侯区科华北路 62 号 1 栋 101' }
print (len (person))
for key in person:
print (key)
字典的运算 对于字典类型来说,成员运算和索引运算肯定是很重要的,前者可以判定指定的键在不在字典中,后者可以通过键获取对应的值或者向字典中添加新的键值对。值得注意的是,字典的索引不同于列表的索引,列表中的元素因为有属于自己有序号,所以列表的索引是一个整数;字典中因为保存的是键值对,所以字典需要用键去索引对应的值。需要特别提醒 大家注意的是,字典中的键必须是不可变类型 ,例如整数(int)、浮点数(float)、字符串(str)、元组(tuple)等类型,这一点跟集合类型对元素的要求是一样的;很显然,之前我们讲的列表(list)和集合(set)不能作为字典中的键,字典类型本身也不能再作为字典中的键,因为字典也是可变类型,但是字典可以作为字典中的值。大家可以先看看下面的代码,了解一下字典的成员运算和索引运算。
person = {'name' : '王大锤' , 'age' : 55 , 'height' : 168 , 'weight' : 60 , 'addr' : '成都市武侯区科华北路 62 号 1 栋 101' }
print ('name' in person)
print ('tel' in person)
print (person['name' ])
print (person['addr' ])
person['age' ] = 25
person['height' ] = 178
person['tel' ] = '13122334455'
person['signature' ] = '你的男朋友是一个盖世垃圾,他会踏着五彩祥云去迎娶你的闺蜜'
print (person)
for key in person:
print (f'{key} :\t{person[key]} ' )
需要注意,在通过索引运算获取字典中的值时,如指定的键没有在字典中,将会引发KeyError异常。为了避免这种情况,推荐使用.get()方法。
字典的方法 字典类型的方法基本上都跟字典的键值对操作相关,其中get方法可以通过键来获取对应的值。跟索引运算不同的是,get方法在字典中没有指定的键时不会产生异常,而是返回None或指定的默认值,代码如下所示。
person = {'name' : '王大锤' , 'age' : 25 , 'height' : 178 , 'addr' : '成都市武侯区科华北路 62 号 1 栋 101' }
print (person.get('name' ))
print (person.get('sex' ))
print (person.get('sex' , True ))
如果需要获取字典中所有的键,可以使用keys方法;如果需要获取字典中所有的值,可以使用values方法。字典还有一个名为items的方法,它会将键和值组装成二元组,通过该方法来遍历字典中的元素也是非常方便的。
person = {'name' : '王大锤' , 'age' : 25 , 'height' : 178 }
print (person.keys())
print (person.values())
print (person.items())
for key, value in person.items():
print (f'{key} :\t{value} ' )
字典的update方法会用一个字典更新另一个字典中的键值对。例如,有两个字典x和y,当执行x.update(y)操作时,x跟y相同的键对应的值会被y中的值更新,而y中有但x中没有的键值对会直接添加到x中,代码如下所示。
person1 = {'name' : '王大锤' , 'age' : 55 , 'height' : 178 }
person2 = {'age' : 25 , 'addr' : '成都市武侯区科华北路 62 号 1 栋 101' }
person1.update(person2)
print (person1)
可以通过pop或popitem方法从字典中删除元素,前者会返回键对应的值,但是如果字典中不存在指定的键,会引发KeyError错误;后者在删除元素时,会返回键和值组成的二元组。字典的clear方法会清空字典中所有的键值对,代码如下所示。
person = {'name' : '王大锤' , 'age' : 25 , 'height' : 178 , 'addr' : '成都市武侯区科华北路 62 号 1 栋 101' }
print (person.pop('age' ))
print (person)
print (person.popitem())
print (person)
person.clear()
print (person)
跟列表一样,从字典中删除元素也可以使用del关键字,在删除元素的时候如果指定的键索引不到对应的值,一样会引发KeyError错误,具体的做法如下所示。
person = {'name' : '王大锤' , 'age' : 25 , 'height' : 178 , 'addr' : '成都市武侯区科华北路 62 号 1 栋 101' }
del person['age' ]
del person['addr' ]
print (person)
进阶用法与注意事项 在实际开发中,除了基础操作,还有一些进阶用法值得注意。
1. 嵌套字典 字典的值可以是任意类型,包括另一个字典。这常用于表示复杂的数据结构,如用户配置或 API 响应。
user_config = {
'info' : {
'name' : 'Alice' ,
'location' : 'Beijing'
},
'settings' : {
'theme' : 'dark' ,
'notifications' : True
}
}
print (user_config['info' ]['name' ])
2. 深浅拷贝 由于字典是可变对象,直接赋值引用的是同一个对象。如果需要复制字典,应使用copy()方法。浅拷贝只复制第一层,深层嵌套的对象仍共享引用。
import copy
original = {'a' : [1 , 2 ], 'b' : 3 }
shallow = original.copy()
deep = copy.deepcopy(original)
shallow['a' ].append(3 )
print (original['a' ])
print (deep['a' ])
3. defaultdict 与 setdefault collections模块提供了defaultdict,可以为缺失的键提供默认工厂函数,避免 KeyError。
from collections import defaultdict
counter = defaultdict(int )
counter['apple' ] += 1
print (counter['apple' ])
print (counter['banana' ])
setdefault方法类似于get,但如果键不存在,它会设置该键并返回默认值,同时修改原字典。
person = {'name' : 'Bob' }
result = person.setdefault('age' , 18 )
print (person)
字典的应用实例 我们通过几个简单的例子来看看如何使用字典类型解决一些实际的问题。
例子 1 :输入一段话,统计每个英文字母出现的次数,按出现次数从高到低输出。
sentence = input ('请输入一段话:' )
counter = {}
for ch in sentence:
if 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' :
counter[ch] = counter.get(ch, 0 ) + 1
sorted_keys = sorted (counter, key=counter.get, reverse=True )
for key in sorted_keys:
print (f'{key} 出现了 {counter[key]} 次.' )
Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.
e 出现了 27 次.
n 出现了 21 次.
a 出现了 18 次.
i 出现了 18 次.
s 出现了 16 次.
t 出现了 16 次.
o 出现了 14 次.
h 出现了 13 次.
r 出现了 10 次.
d 出现了 9 次.
l 出现了 9 次.
g 出现了 6 次.
u 出现了 6 次.
f 出现了 6 次.
c 出现了 6 次.
y 出现了 5 次.
b 出现了 5 次.
m 出现了 4 次.
p 出现了 3 次.
w 出现了 2 次.
v 出现了 2 次.
M 出现了 1 次.
k 出现了 1 次.
x 出现了 1 次.
例子 2 :在一个字典中保存了股票的代码和价格,找出股价大于 100 元的股票并创建一个新的字典。
stocks = {
'AAPL' : 191.88 ,
'GOOG' : 1186.96 ,
'IBM' : 149.24 ,
'ORCL' : 48.44 ,
'ACN' : 166.89 ,
'FB' : 208.09 ,
'SYMC' : 21.29
}
stocks2 = {key: value for key, value in stocks.items() if value > 100 }
print (stocks2)
{'AAPL': 191.88 , 'GOOG': 1186.96 , 'IBM': 149.24 , 'ACN': 166.89 , 'FB': 208.09 }
config = {
'database' : {
'host' : 'localhost' ,
'port' : 3306 ,
'user' : 'root'
},
'cache' : {
'enabled' : True ,
'ttl' : 3600
}
}
host = config.get('database' , {}).get('host' , '127.0.0.1' )
print (f'连接数据库地址:{host} ' )
总结 Python 程序中的字典跟现实生活中字典非常像,允许我们以键值对的形式保存数据 ,再通过键索引对应的值 。这是一种非常有利于数据检索 的数据类型。再次提醒大家注意,字典中的键必须是不可变类型 ,字典中的值可以是任意类型。
掌握字典的使用是 Python 编程的基础,它在数据处理、缓存管理、JSON 解析等场景中无处不在。建议多动手编写代码练习,熟悉各种方法的细节,以便在实际项目中灵活应用。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online