python 合并多个字典或映射

问题

现在有多个字典或者映射,你想将它们从逻辑上合并为一个单一的映射后执行某些操作, 比如查找值或者检查某些键是否存在。

实现

通过 collections 模块中的 ChainMap 类来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
>>> from collections import ChainMap

>>> a = {'x': 1, 'z': 3 }
>>> b = {'y': 2, 'z': 4 }
>>> merge = ChainMap(a, b) # merge 具有 dict 的一般特性, 可以用操作字典的方式操作它。
>>> maps = merge.maps
[{'x': 1, 'z': 3}, {'y': 2, 'z': 4}]

# 操作方法
# 下述方法中 D is merge
>>> [x for x in dir(merge) if '__' not in x]
['_abc_impl', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'maps', 'new_child', 'parents', 'pop', 'popitem', 'setdefault', 'update', 'values']

# merge.clear()
Clear maps[0], leaving maps[1:] intact.
>>> merge.clear()
>>> a
{}
>>> b
{'y': 2, 'z': 4}
>>> merge
ChainMap({}, {'y': 2, 'z': 4})

# merge.copy(self)
New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]

# merge.get(key, default=None)
D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.

# merge.new_child(m=None)
New ChainMap with a new map followed by all previous maps.
If no map is provided, an empty dict is used.

# merge.pop(key, *args)
Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].

# merge.popitem()
Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.

# merge.fromkeys(iterable, *args) from abc.ABCMeta
Create a ChainMap with a single dict created from the iterable.

# merge.parents
New ChainMap from maps[1:].

# merge.setdefault(key, default=None)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D and add in maps[0]

# merge.update(*args, **kwds)
D.update([E, ]**F) -> None. Update D from mapping/iterable E and F.
If E present and has a .keys() method, does: for k in E: D[k] = E[k]
If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v
In either case, this is followed by: for k, v in F.items(): D[k] = v

# merge.items()
D.items() -> a set-like object providing a view on D's items

# merge.keys()
D.keys() -> a set-like object providing a view on D's keys

# merge.values()
D.values() -> an object providing a view on D's values

说明

  • 一个 ChainMap 接受多个字典并将它们在逻辑上变为一个字典。
    这些字典并不是真的合并在一起了, ChainMap 类只是在内部创建了一个容纳这些字典的列表并重新定义了一些常见的字典操作来遍历这个列表。
  • 如果出现重复键,那么第一次出现的映射值会被返回。
  • 对于字典的更新或删除操作总是影响的是列表中第一个字典。
  • 与 update() 方法将两个字典合并不同的是,ChainMap 使用原来的字典,它自己不创建新的字典。故原字典改变,ChainMap 创建的类字典也会跟着改变。
-------------本文结束感谢您的阅读-------------