一、简介
在计算机科学领域,字典是一种很常用且重要的数据结构之一。字典的作用类似于电话薄,通过名称查找到电话号码,字典则是用 键 来查找对应的对象。
在Python的标准库中,有好几种字典实现方式,他们各自的功能也不尽相同,针对几种实际代码中可能用到的实现方式,这里做一下简单介绍
二、实现方式
1、dict
dict 字典在Python中同其他基础类型一样,有着举足轻重的地位,并且支持多种语法糖,能快速上手使用,下面是实现方式。
# 花括号实现
phonebook = {
'bob': 7387,
'alice': 3719,
'jack': 7052,
}
# 字典解析式实现
squares = {x * x for x in range(10)}
Python的字典以可散列类型作为索引,因为可散列类型在生命周期内不会改变其散列值__hash__,并且可以与其他对象进行比较。
所以,作为字典键,必须使用可散列类型,如上方例子中就是使用的字符串和数字这样的可散列类型。另外,元组对象也是可以作为字典键的,但元组中必须只包含可散列类型。
大部分情况下,只需要使用Python的标准字典就可以满足大部分需求。但也存在一些针对特殊需要实现的字典,他们都基于内置字典类实现。
2、其他字典实现
(1). collections.OrderedDict —— 能记住键的插入顺序
import collections
d = collections.OrderedDict(one=1, two=2, three=3)
print(d)
d["four"] = 4
print(d.keys())
输出如下
OrderedDict([('one', 1), ('two', 2), ('three', 3)])
odict_keys(['one', 'two', 'three', 'four'])
(2). collections.defaultdict——为缺失的键返回默认值
defaultdict 的构造函数接受一个可调用对象,查找时如果找不到给定的键,就返回这个可调用对象,与使用get()方法或者捕获KeyError异常相比,这中方式的代码量较少,并能清晰地表达出程序员的意图。
from collections import defaultdict
dd = defaultdict(list)
dd["dog"].append("Rufus")
dd["dog"].append("Kathrin")
dd["dog"].append("Mr Sniffles")
print(dd["dog"])
输出如下
['Rufus', 'Kathrin', 'Mr Sniffles']
(3). collections.ChainMap——搜索多个字典
将多个字典分组到一个映射中,在查找时逐个搜索底层映射,直到找到第一个符合条件的键。对ChainMap进行插入、更新和删除操作,只会作用于其中的第一个字典。
from collections import ChainMap
dict1 = {'one': 1, 'two': 2}
dict2 = {'three': 3, 'four': 4}
chain = ChainMap(dict1, dict2)
print(chain)
print(chain["three"])
print(chain["one"])
输出如下
ChainMap({'one': 1, 'two': 2}, {'three': 3, 'four': 4})
3
1
(4). types.MappingProxyType —— 用于创建只读字典
from types import MappingProxyType
writable = {'one': 1, 'two': 2}
read_only = MappingProxyType(writable)
print(read_only["one"])
read_only["one"] = 10 ## 修改字典会抛出异常
writable["one"] = 42 ## 更新原字典会影响到代理
print(read_only)
三、总结
一般情况下,在代码中使用Python内置dict字典数据类型,这是优化过的散列表实现,拥有大部分功能并且内置到了核心语言中。
如果有dict无法实现的特殊需求,比如要求字典键具有顺序,或者字典值具有默认值等,使用以上基于dict实现的扩展数据类型。
更多关于dict 的标准库接口, 见此文档