【问题标题】:Is there better way to merge dictionaries contained in two lists in Python? [closed]有没有更好的方法来合并 Python 中两个列表中包含的字典? [关闭]
【发布时间】:2016-04-06 13:59:55
【问题描述】:

我有两个包含字典的列表:

list_a:

[{'id': 1, 'name': 'test'}, {'id': 2, 'name': 'test1'},....]

list_b:

[{'id': 1, 'age': 10}, {'id': 2, 'age': 20}, ....]

我想合并这两个列表,结果是:

[{'id': 1, 'name': 'test', 'age': 10}, {'id': 2, 'name': 'test1', 'age': 20}....]

我想使用嵌套循环来制作它:

result= []
for i in list_a:
   for j in list_b:
     if i['id'] == j['id']:
      i['age']=j['age']
      result.append(i)

但是list_a有2000个元素,list_b的id是属于list_a的,但是list_b的个数可能小于2000。这种方法时间复杂度太高,有没有更好的合并方式?

【问题讨论】:

  • 我猜你想要 "name": "test1" 在你的第二个合并字典中?
  • 我投票决定将此问题作为题外话结束,因为这是一个性能问题,而不是调试问题,这意味着它属于 Code Review,而不是 Stack Overflow。 codereview.stackexchange.com
  • @ArtOfWarfare Stack Overflow 用于特定问题,不一定仅用于调试。也就是说,我认为这个问题对于 Stack Overflow 来说“过于宽泛”,因为有太多可能的答案,因此我投票决定关闭它。
  • 你的意图我不清楚,因为你对合并时处理公共字段只字未提。

标签: python list


【解决方案1】:

不是真的,但 dict.setdefaultdict.update 可能是你的朋友。

data = {}
lists = [
   [{'id': 1, 'name': 'test'}, {'id': 2, 'name': 'test1'},],
   [{'id': 1, 'age': 10}, {'id': 2, 'age': 20},]
]

for each_list in lists:
   for each_dict in each_list:
       data.setdefault(each_dict['id'], {}).update(each_dict)

结果:

>>> data
{1: {'age': 10, 'id': 1, 'name': 'test'},
 2: {'age': 20, 'id': 2, 'name': 'test1'}}

通过这种方式,您可以通过 id 进行查找(或者如果您想要一个简单的列表,只需获取 data.values())。自从我上算法课以来已经 20 年了,但我想这已经足够接近 O(n) 而你的样本更多的是 O(n²)。这个解决方案有一些有趣的特性:不会改变原始列表,适用于任意数量的列表,适用于包含不同“id”集的不均匀列表。

【讨论】:

    【解决方案2】:
    answer = {}
    for d in list_a: answer[d['id']] = d
    
    for d in list_b:
        if d['id'] not in d:
            answer[d['id']] = d
            continue
        for k,v in d.items():
            answer[d['id']][k] = v
    
    answer = [d for k,d in sorted(answer.items(), key=lambda s:s[0])]
    

    【讨论】:

      【解决方案3】:

      不,我认为这是最好的方法,因为您将所有数据连接到最简单的数据结构中。

      你可以知道如何实现它here

      希望我的回答对你有所帮助。

      【讨论】:

        【解决方案4】:

        这可以在一行中完成,因为 list1 和 list2 中的项目顺序相同,id 明智,我的意思是。

        result = [item1 for item1, item2 in zip(list1, list2) if not item1.update(item2)]
        

        长篇大论

        for item1, item2 in zip(list1, list2):
            item1.update(item2)
            # list1 will be mutated to the result
        

        【讨论】:

          【解决方案5】:

          要找到一种更好的方法,需要了解这些值是如何生成的以及如何使用它们。

          例如,如果您将它们作为 csv 文件,您可以使用类似表格的模块,例如 pandas(我将从您的列表中创建它们,但它们也有 read_csvfrom_csv):

          import pandas as pd
          df1 = pd.DataFrame.from_dict([{'id': 1, 'name': 'test'}, {'id': 2, 'name': 'test1'}])
          df2 = pd.DataFrame.from_dict([{'id': 1, 'age': 10}, {'id': 2, 'age': 20}])
          pd.merge(df1, df2, on='id')
          

          或者如果它们来自数据库,大多数数据库已经有一个JOIN ON(例如MYSQL)选项。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-07-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多