合并具有相同键值的单个词典列表

2024-10-06 12:39:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我可以在这里看到许多类似的问题,但我找不到一个可以帮助我获得所需输出的问题

我有一个具有相同ID但具有不同键值对的字典列表,我想将所有这些键值对合并到一个列表条目中,下面是数据示例和所需的输出

谢谢你的帮助

data = [
    {'id': '10', 'animal' : 'cat'},
    {'id': '11', 'animal' : 'dog'},
    {'id': '3', 'animal' : 'pigeon'},
    {'id': '10', 'color' : 'yellow'},
    {'id': '11', 'color' : 'brown'},
    {'id': '3', 'color' : 'grey'},
    {'id': '10', 'type' : 'furry'},
    {'id': '11', 'type' : 'fluffy'},
    {'id': '3', 'type' : 'dirty'},
]

期望输出

data = [
    {'id': '10', 'animal' : 'cat', 'color' : 'yellow', 'type' : 'furry'},
    {'id': '11', 'animal' : 'dog', 'color' : 'brown', 'type' : 'fluffy'},
    {'id': '3', 'animal' : 'pigeon', 'color' : 'grey', 'type' : 'dirty'},
]

Tags: id列表datatypecatcolorgrey键值
3条回答

在Python3.9(ETA Fall 2020)中,您将能够使用|操作符将dict与相同的id键合并

from itertools import groupby
from operator import or_, itemgetter
from functools import reduce

# I know *why* groupby doesn't have an option to
# sort your data first, but that doesn't mean I can't
# wish that it could...
def group(data, key):
    "Iterate over groups of dicts considered equal according to key"
    yield from map(itemgetter(1), groupby(sorted(data, key=key), key))

data = [
    {'id': '10', 'animal' : 'cat'},
    {'id': '11', 'animal' : 'dog'},
    {'id': '3', 'animal' : 'pigeon'},
    {'id': '10', 'color' : 'yellow'},
    {'id': '11', 'color' : 'brown'},
    {'id': '3', 'color' : 'grey'},
    {'id': '10', 'type' : 'furry'},
    {'id': '11', 'type' : 'fluffy'},
    {'id': '3', 'type' : 'dirty'},
    ]


# E.g., {'id': 10, 'animal': 'cat'} | {'id': 10, 'color': 'yellow'}
#  == {'id': 10, 'animal': 'cat', 'color': 'yellow'}
data = [reduce(or_, ds) for ds in group(data, itemgetter('id'))]

实现这一点有多种方法,其中之一是defaultdict

In [1]: data = [
   ...:     {'id': '10', 'animal' : 'cat'},
   ...:     {'id': '11', 'animal' : 'dog'},
   ...:     {'id': '3', 'animal' : 'pigeon'},
   ...:     {'id': '10', 'color' : 'yellow'},
   ...:     {'id': '11', 'color' : 'brown'},
   ...:     {'id': '3', 'color' : 'grey'},
   ...:     {'id': '10', 'type' : 'furry'},
   ...:     {'id': '11', 'type' : 'fluffy'},
   ...:     {'id': '3', 'type' : 'dirty'},
   ...: ]

In [2]: from collections import defaultdict
   ...: ids = defaultdict(dict)
   ...: for d in data:
   ...:     ids[d["id"]].update(d)
   ...:


In [6]: list(ids.values())
Out[6]:
[{'id': '10', 'animal': 'cat', 'color': 'yellow', 'type': 'furry'},
 {'id': '11', 'animal': 'dog', 'color': 'brown', 'type': 'fluffy'},
 {'id': '3', 'animal': 'pigeon', 'color': 'grey', 'type': 'dirty'}]

您可以使用groupbyChainMap来完成它

from itertools import groupby
from collections import ChainMap

id_getter = lambda x: x['id']
gp = groupby(sorted(data, key=id_getter), key=id_getter)
result = [dict(ChainMap(*a)) for _, a in gp]

groupby处理已排序的集合,因此在调用groupby
之前对data进行排序 ChainMap用于将词典列表合并到单个词典中

相关问题 更多 >