Python 字典类型拓展(包括 MappingProxyType 只读字典, defaultdict 缺省字典和 ChainMap)

Python 除了 dict 字典类型, 还有相关的字典扩展类型, 包括MappingProxyType 只读字典, defaultdict 缺省字典和 ChainMap


MappingProxyType 只读字典

MappingProxyType 为普通字典提供只读视图

除了无法修改, 只读字典与普通字典的功能一致


  • 只读字典运算:
>>> from types import MappingProxyType
>>> w = {
    
    'ide': 'PyCharm'}
>>> r = MappingProxyType(w)
>>> len(r)
1
>>> r['ide']
'PyCharm'
# 无法修改
>>> r['language'] = 'Python'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item assignment
# 成员运算
>>> 'ide' in r
True
# 比较运算, 与原字典相等
>>> r == w
True
# 并集(Python 3.9 新增), 因本身不可修改, 返回了新的字典
>>> r | {
    
    'language': 'Python'}
{
    
    'ide': 'PyCharm', 'language': 'Python'}

更新原字典后, 只读字典会同步修改

>>> w['version'] = '3.9'
>>> r
mappingproxy({
    
    'ide': 'PyCharm', 'version': '3.9'})
  • 只读字典方法:
>>> r.get('language', 'Go')
'Go'
# 只读字典也支持 keys(), values(), items() 方法
>>> for k, v in r.items():
...     print(f"{
      
      k}:{
      
      v}")
... 
ide:PyCharm
version:3.9

defaultdict 缺省字典

当字典的键不存在时, defaultdict 使用工厂函数的返回值作为这个键对应的值


常用的工厂函数有 int, list 等, 不传参数时返回一个工厂默认值

>>> int()
0
>>> list()
[]

使用缺省字典

>>> from collections import defaultdict
>>> dd = defaultdict(list)
# 键不存在时, 调用工厂函数(没有参数的调用), 将返回值(空列表)作为字典的值
>>> dd['other']
[]
>>> dd['ide'].append('VSCode')
>>> dd
defaultdict(<class 'list'>, {
    
    'other': [], 'ide': ['VSCode']})

在底层 defaultdict 比普通字典 dict 多实现了 __missing__ 方法, 在字典的键不存在时, 该方法会被调用


ChainMap

ChainMap 将多个字典组成一个映射数据结构, 在使用上与字典一致

  1. 通过键访问值时, 优先返回第一个包含该键的字典的值
  2. 修改 ChainMap 时, 仅更新第一个字典

>>> from collections import ChainMap
>>> d_1 = {
    
    'one': 1, 'two': 2}
>>> d_2 = {
    
    'two': 0, 'six': 6}
>>> d = ChainMap(d_1, d_2)
# 访问 ChainMap
>>> d['two']
2
# 修改 ChainMap
>>> d['ten'] = 10
# 实际修改了第一个字典
>>> d_1
{
    
    'one': 1, 'two': 2, 'ten': 10}

# 与普通字典一样的使用
>>> list(d.keys())
['two', 'six', 'one', 'ten']
>>> list(d.values())
[2, 6, 1, 10]
>>> d.get('other', 0)
0

在底层 ChainMap 的 maps 属性保存了所有的字典

>>> d.maps
[{
    
    'one': 1, 'two': 2, 'ten': 10}, {
    
    'two': 0, 'six': 6}]

猜你喜欢

转载自blog.csdn.net/jiang_huixin/article/details/125999970
今日推荐