合并多个键不一致的字典

我是一名 Python 初学者,正在努力解决以下问题:


我正在尝试将多个列表与从多个 json 解码的嵌套字典合并。列表之间的共同点是每个嵌套字典的“uid”键对应于一个名称,但问题是某些字典的键名称不同。例如,代替“uid”,字典可能有“number”作为键。我想将它们的一部分合并到一个超级嵌套字典列表中。为了说明,我所拥有的是:


masterlist = [ ]


listA = [{"uid": "12345", "name": "John Smith"}, {etc...}]


listB = [{"number": "12345", "person": "John Smith", "val1": "25"}, {etc...}]


listC = [{"number": "12345", "person": "John Smith", "val2": "65"}, {etc...}]

我想结束的是:


masterlist = [{"uid": "12345", "name": "John Smith", "val1": "25", "val2: "65"}, {etc...}]

这是否可以通过迭代和比较相同的“uid”值来有效/pythonically 完成?我已经看到很多关于通过匹配键进行合并的操作方法,但这里的问题显然是键不一致。排序无所谓。我所需要的只是让主列表包含每个 dict 条目的相应 uid、名称和值。希望这是有道理的,谢谢!


泛舟湖上清波郎朗
浏览 212回答 3
3回答

慕标琳琳

可能有使用 base python 的解决方案,但我能想到的最简单的方法是使用 pandas 库将每个列表转换为 DataFrame,然后将它们连接/合并在一起。import pandas as pddfA = pd.DataFrame(listA)dfB = pd.DataFrame(listB)merged_df = dfA.merge(dfB, left_on='uid', right_on='number')这将返回一个包含比您需要的更多列的 DataFrame(即“uid”和“number”都有列),但您可以通过这种方式指定您想要的列以及您想要它们的顺序:merged_df = merged_df[['uid', 'name', 'val1']]要将多个 DataFrames 合并到一个主框架中,请参见此处:pandasthree -way joins multiple dataframes on columns

慕雪6442864

您可以在没有 Pandas 的情况下使用列表推导式来完成此操作,该推导式构建字典字典,按“uid”对列表字典进行分组。然后使用该分组字典的 .values() 再次获取字典列表:listA = [{"uid": "12345", "name": "John Smith"},{"uid": "67890", "name": "Jane Doe"}]listB = [{"number": "12345", "person": "John Smith", "val1": "25"},{"number": "67890", "val1": "37"}]listC = [{"number": "12345", "person": "John Smith", "val2": "65"},{"number": "67890", "val2": "53"}]from collections import defaultdictfn     = { "number":"uid", "person":"name" } # map to get uniform key namesdata   = [ { fn.get(k,k):v for k,v in d.items() } for d in listA+listB+listC ]result = next(r for r in [defaultdict(dict)] if [r[d["uid"]].update(d) for d in data])print(*result.values()){'uid': '12345', 'name': 'John Smith', 'val1': '25', 'val2': '65'} {'uid': '67890', 'name': 'Jane Doe', 'val1': '37', 'val2': '53'}

慕神8447489

您应该将所有输入列表放在列表列表中,以便您可以构建一个映射uid到具有聚合项目值的 dict 的 dict,这样您所需的 dict 列表将只是映射的 dict 值。为了允许在不同的输入字典中对键的命名不一致,pop您不想要的那些(例如number和id在我的示例中)并使用您想要保留的键分配给字典(例如uid在示例中):wanted_key = 'uid'unwanted_keys = {'number', 'id'}mapping = {}for l in lists:    for d in l:        if wanted_key not in d:            d[wanted_key] = d.pop(unwanted_keys.intersection(d).pop())        mapping.setdefault(d[wanted_key], {}).update(d)masterlist = list(mapping.values())所以给出:lists = [    [        {"uid": "12345", "name": "John Smith"},        {"uid": "56789", "name": "Joe Brown", "val1": "1"}    ],    [        {"number": "12345", "name": "John Smith", "val1": "25"},        {"number": "56789", "name": "Joe Brown", "val2": "2"}    ],    [        {"id": "12345", "name": "John Smith", "val2": "65"}    ]]masterlist 变成:[    {'uid': '12345', 'name': 'John Smith', 'val1': '25', 'val2': '65'},    {'uid': '56789', 'name': 'Joe Brown', 'val1': '1', 'val2': '2'}]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python