![3c6104640bbd419ede01b8bbb7096b3c.png](https://img-blog.csdnimg.cn/img_convert/3c6104640bbd419ede01b8bbb7096b3c.png)
1. 原地更新
字典对象内置了一个 update 方法,用于把另一个字典更新到自己身上。
>>> profile = {"name": "xiaoming", "age": 27}
>>> ext_info = {"gender": "male"}
>>>
>>> profile.update(ext_info)
>>> print(profile)
{'name': 'xiaoming', 'age': 27, 'gender': 'male'}
如果想使用 update 这种最简单、最地道原生的方法,但又不想更新到自己身上,而是生成一个新的对象,那请使用深拷贝。
>>> profile = {"name": "xiaoming", "age": 27}
>>> ext_info = {"gender": "male"}
>>>
>>> from copy import deepcopy
>>>
>>> full_profile = deepcopy(profile)
>>> full_profile.update(ext_info)
>>>
>>> print(full_profile)
{'name': 'xiaoming', 'age': 27, 'gender': 'male'}
>>> print(profile)
{"name": "xiaoming", "age": 27}
2. 先解包再合并
使用**可以序列解包,解包以后可以再使用{ }或者dict合并
>>> profile = {"name": "xiaoming", "age": 27}
>>> ext_info = {"gender": "male"}
>>>
>>> full_profile01 = {**profile, **ext_info}
>>> print(full_profile01)
{'name': 'xiaoming', 'age': 27, 'gender': 'male'}
>>>
>>> full_profile02 = dict(**profile, **ext_info)
>>> print(full_profile02)
{'name': 'xiaoming', 'age': 27, 'gender': 'male'}
3. 使用itertools
python内置的强大的功能模块,可以操作可迭代对象
正好我们字典也是可迭代对象,自然就可以想到,可以使用itertools.chain()
函数先将多个字典(可迭代对象)串联起来,组成一个更大的可迭代对象,然后再使用 dict 转成字典。
>>> import itertools
>>>
>>> profile = {"name": "xiaoming", "age": 27}
>>> ext_info = {"gender": "male"}
>>>
>>>
>>> dict(itertools.chain(profile.items(), ext_info.items()))
{'name': 'xiaoming', 'age': 27, 'gender': 'male'}
4. 使用ChainMap
如果可以引入一个辅助包,ChainMap
也可以达到和itertools
同样的效果。
>>> from collections import ChainMap
>>>
>>> profile = {"name": "xiaoming", "age": 27}
>>> ext_info = {"gender": "male"}
>>>
>>> dict(ChainMap(profile, ext_info))
{'name': 'xiaoming', 'age': 27, 'gender': 'male'}
使用 ChainMap 有一点需要注意,当字典间有重复的键时,只会取第一个值,排在后面的键值并不会更新掉前面的(使用 itertools 就不会有这个问题)。
>>> from collections import ChainMap
>>>
>>> profile = {"name": "xiaoming", "age": 27}
>>> ext_info={"age": 30}
>>> dict(ChainMap(profile, ext_info))
{'name': 'xiaoming', 'age': 27}
另外这里穿插介绍collections内置库中的另外一个强大的功能模块:Counter
以下将是一个很长的篇幅!
其实Counter是dict类的子类,但是可以实现Counter不能实现的一些功能。因此当我们创建字典的时候,也可以从字典开始创建。
class Counter(dict):
def __init__(*args, **kwds):
if not args:
raise TypeError("descriptor '__init__' of 'Counter' object " "needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
super(Counter, self).__init__()
self.update(*args, **kwds)
Counter类的创建
下面是四种创建的方法:
>>> c = Counter() # 创建一个空的Counter类
>>> c = Counter('gallahad') # 从一个可iterable对象(list、tuple、dict、字符串等)创建
>>> c = Counter({'a': 4, 'b': 2}) # 从一个字典对象创建
>>> c = Counter(a=4, b=2) # 从一组键值对创建
一般来说,我们经常使用第三种,比如我们在统计字典中每个单词出现次数的时候:
c = Counter(ans)
topk = c.most_common(n = k) # list(tuple1, tuple2,...,),取出现次数最多的k个
ans = dict((a[0], i) for i, a in enumerate(topk)) # 再转化为字典
更多的方法和骚操作可参考这篇collections模块—— Counter
5. 最酷炫的字典解析式
别的不说,具体示例代码如下:
>>> profile = {"name": "xiaoming", "age": 27}
>>> ext_info = {"gender": "male"}
>>>
>>> {k:v for d in [profile, ext_info] for k,v in d.items()}
{'name': 'xiaoming', 'age': 27, 'gender': 'male'}