Python高级特性(五)——字典、散列和散列表

一、简介

在计算机科学领域,字典是一种很常用且重要的数据结构之一。字典的作用类似于电话薄,通过名称查找到电话号码,字典则是用 来查找对应的对象。

在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 的标准库接口, 见此文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值