【问题标题】:Convert a list of dictionaries with similar/duplicate keys into a single dictionary (values would be list) using reduce method [duplicate]使用reduce方法将具有相似/重复键的字典列表转换为单个字典(值将是列表)[重复]
【发布时间】:2017-12-11 06:10:02
【问题描述】:

这个问题类似于帖子“Python - Convert list of single key dictionaries into a single dictionary”,假设我们保证字典列表中的不同键。我的问题是,如果我们有相似的键怎么办?我们如何利用 reduce 函数。

例如,我们有:

lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}]

我们想成为:

dict = {'1': ['A', 'B'], '2': ['C', 'D'], '3': ['E']}

另外,How to merge multiple dicts with same key? 的帖子也是类似的,只是这里我们要使用reduce方法。

【问题讨论】:

  • 为什么使用reduce?它必须使用reduce吗?
  • 请尝试一下,如果卡住了再回来问。
  • @wwii 我真的很想知道为什么这个评论没问题,同时试图评论“你试过什么?”你从 SO 那里收到一条消息,告诉你你不能这样做。
  • @ViníciusAguiar - 不清楚你在问我什么。
  • @ViníciusAguiar 您无法发布该内容的原因是it's been used to death to link to certain websites。老实说,它变得非常粗鲁。如果用户没有尝试过任何事情,请告知他们需要付出努力,如果在此过程中有问题,请返回。

标签: python dictionary


【解决方案1】:

好的,从链接的问题中获得灵感,您可以这样做:

In [12]: from collections import defaultdict
    ...: from functools import reduce

In [13]: lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}]

In [14]: def foo(r, d):
    ...:     for k in d:
    ...:         r[k].append(d[k])
    ...:         

In [16]: d = reduce(lambda r, d: foo(r, d) or r, lst, defaultdict(list))

In [17]: d
Out[17]: defaultdict(list, {'1': ['A', 'B'], '2': ['C', 'D'], '3': ['E']})

您需要一个中间函数来进行更新...我认为有更好的方法来做到这一点,但这就是它的症结所在。


现在,如果你想要一种更简洁、更易读的方式,你可以这样做:

In [12]: from collections import defaultdict

In [30]: lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}]

In [31]: d = defaultdict(list)

In [32]: for i in lst:
    ...:     k, v = list(i.items())[0] # an alternative to the single-iterating inner loop from the previous solution
    ...:     d[k].append(v)
    ...:     

In [33]: d
Out[33]: defaultdict(list, {'1': ['A', 'B'], '2': ['C', 'D'], '3': ['E']})

【讨论】:

  • .. 是的,不需要使用 reduce。
  • 另请注意,您必须从 collections 导入 defaultdict() 才能使用第二种方法。
  • @ChristianDean 已修复!
  • 我制定了如下所示的解决方案,但我认为这是一个更好的解决方案,我应该在此处的评论下评论我的解决方案还是保持原样?
  • @tiba 就我个人而言,您的解决方案只是我的一个稍微有点风的版本,而且由于他们以同样的方式做同样的事情,您可能会删除它。但把它留在身边也没有什么坏处。
【解决方案2】:

您可以使用字典对象的setdefault() 属性:

>>> def combine(dictionaries):
    combined_dict = {}
    for dictionary in dictionaries:
        for key, value in dictionary.items():
            combined_dict.setdefault(key, []).append(value)
    return combined_dict

>>> 
>>> lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}]
>>> combine(lst)
{'1': ['A', 'B'], '2': ['C', 'D'], '3': ['E']}
>>> 

这基本上是通过首先检查新字典中是否已经存在键来工作的。如果是这样,我们只需将当前值附加到同一个键上。如果不是,我们创建一个新键并将当前值附加到该键。

【讨论】:

    【解决方案3】:

    我刚刚想出了一个使用reduce方法的函数的解决方案。

    首先我们定义一个函数来检查key之前是否被插入到dict中。如果它是一个新键,我们将其添加到带有列表中值的字典中,如果它已经存在,我们将值附加到现有列表中。

    def dict_list(each_dict):
        d_key = each_dict.keys()[0]
        d_value = each_dict.values()[0]
        if d_key in return_dict:
            return_dict[d_key].append(d_value)
        else:
            return_dict[d_key] = [d_value]
        return return_dict
    

    然后在一行中使用这个函数和reduce,如下所示:

    lst = [{'1': 'A'}, {'1': 'B'}, {'2': 'C'}, {'2': 'D'}, {'3': 'E'}]
    return_dict = {}
    print reduce(lambda return_dict, each_dict: dict_list(each_dict), lst, {})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 1970-01-01
      • 2015-04-03
      • 2022-01-19
      • 2019-11-27
      • 2020-03-19
      • 2011-10-17
      相关资源
      最近更新 更多