Thi*_*dge 5 python merge dictionary list
当两个列表的长度不同(使用 Python 3.6)时,我想在一个键上合并两个字典列表。例如,如果我们有一个名为 的字典列表l1:
l1 = [{'pcd_sector': 'ABDC', 'coverage_2014': '100'},
{'pcd_sector': 'DEFG', 'coverage_2014': '0'}]
Run Code Online (Sandbox Code Playgroud)
和另一个名为 dicts 的列表l2:
l2 = [{'pcd_sector': 'ABDC', 'asset': '3G', 'asset_id': '2gs'},
{'pcd_sector': 'ABDC', 'asset': '4G', 'asset_id': '7jd'},
{'pcd_sector': 'DEFG', 'asset': '3G', 'asset_id': '3je'},
{'pcd_sector': 'DEFG', 'asset': '4G', 'asset_id': '8js'},
{'pcd_sector': 'CDEF', 'asset': '3G', 'asset_id': '4jd'}]
Run Code Online (Sandbox Code Playgroud)
如何将它们合并使用pcd_sector以获得此(?):
result = [{'pcd_sector': 'ABDC', 'asset': '3G', 'asset_id': '2gs', 'coverage_2014': '100'},
{'pcd_sector': 'ABDC', 'asset': '4G', 'asset_id': '7jd', 'coverage_2014': '100'},
{'pcd_sector': 'DEFG', 'asset': '3G', 'asset_id': '3je', 'coverage_2014': '0'},
{'pcd_sector': 'DEFG', 'asset': '4G', 'asset_id': '8js', 'coverage_2014': '0'},
{'pcd_sector': 'CDEF', 'asset': '3G', 'asset_id': '4jd'}]
Run Code Online (Sandbox Code Playgroud)
到目前为止我尝试过的
我使用以下代码合并了两个列表,但不幸的是我最终得到了一个简短版本,而不是所需的完整数据结构。
import pprint
grouped = {}
for d in l1 + l2:
grouped.setdefault(d['pcd_sector'], {'asset':0, 'asset_id':0, 'coverage_2014':0}).update(d)
result = [d for d in grouped.values()]
pprint.pprint(result)
Run Code Online (Sandbox Code Playgroud)
所以当我运行代码时,我最终得到了这个简短的输出:
result = [{'pcd_sector': 'ABDC', 'asset': '3G', 'asset_id': '2gs', 'coverage_2014': '100'},
{'pcd_sector': 'DEFG', 'asset': '4G', 'asset_id': '8js', 'coverage_2014': '0'},
{'pcd_sector': 'CDEF', 'asset': '3G', 'asset_id': '4jd'}]
Run Code Online (Sandbox Code Playgroud)
您的方法中的问题是您的数据被放入一个grouped带有'pcd_sector'as 键的字典中,但您l2有多个具有相同的字典'pcd_sector'。您可以使用元组'pcd_sector', 'asset'作为 的键l2,但它不再适用l1。所以需要分两步进行处理,而不是l1 + l2直接迭代。
如果pcd_sector键在 中是唯一的l1,您可以创建一个大字典而不是小字典列表:
>>> d1 = {d['pcd_sector']:d for d in l1}
>>> d1
{'ABDC': {'pcd_sector': 'ABDC', 'coverage_2014': '100'}, 'DEFG': {'pcd_sector': 'DEFG', 'coverage_2014': '0'}}
Run Code Online (Sandbox Code Playgroud)
然后,您只需合并具有相同键的字典即可pcd_sector:
>>> [dict(d, **d1.get(d['pcd_sector'], {})) for d in l2]
[{'asset_id': '2gs', 'coverage_2014': '100', 'pcd_sector': 'ABDC', 'asset': '3G'}, {'asset_id': '7jd', 'coverage_2014': '100', 'pcd_sector': 'ABDC', 'asset': '4G'}, {'asset_id': '3je', 'coverage_2014': '0', 'pcd_sector': 'DEFG', 'asset': '3G'}, {'asset_id': '8js', 'coverage_2014': '0', 'pcd_sector': 'DEFG', 'asset': '4G'}, {'asset_id': '4jd', 'pcd_sector': 'CDEF', 'asset': '3G'}]
Run Code Online (Sandbox Code Playgroud)
把它们放在一起,代码就变成了:
l1 = [{'pcd_sector': 'ABDC', 'coverage_2014': '100'},
{'pcd_sector': 'DEFG', 'coverage_2014': '0'}]
l2 = [{'pcd_sector': 'ABDC', 'asset': '3G', 'asset_id': '2gs'},
{'pcd_sector': 'ABDC', 'asset': '4G', 'asset_id': '7jd'},
{'pcd_sector': 'DEFG', 'asset': '3G', 'asset_id': '3je'},
{'pcd_sector': 'DEFG', 'asset': '4G', 'asset_id': '8js'},
{'pcd_sector': 'CDEF', 'asset': '3G', 'asset_id': '4jd'}]
d1 = {d['pcd_sector']:d for d in l1}
result = [dict(d, **d1.get(d['pcd_sector'], {})) for d in l2]
import pprint
pprint.pprint(result)
# [{'asset': '3G',
# 'asset_id': '2gs',
# 'coverage_2014': '100',
# 'pcd_sector': 'ABDC'},
# {'asset': '4G',
# 'asset_id': '7jd',
# 'coverage_2014': '100',
# 'pcd_sector': 'ABDC'},
# {'asset': '3G',
# 'asset_id': '3je',
# 'coverage_2014': '0',
# 'pcd_sector': 'DEFG'},
# {'asset': '4G',
# 'asset_id': '8js',
# 'coverage_2014': '0',
# 'pcd_sector': 'DEFG'},
# {'asset': '3G', 'asset_id': '4jd', 'pcd_sector': 'CDEF'}]
Run Code Online (Sandbox Code Playgroud)