【问题标题】:Merging a number of dictionaries maintaining duplicate values, but merging duplicate keys in Python合并多个维护重复值的字典,但在 Python 中合并重复键
【发布时间】:2017-10-04 02:08:28
【问题描述】:

我的合并字典的代码有问题。这是我得到的:

output1 = {'children': 
                    {'children':
                              {'children': 
                                        {'name': 'thriller.mp3', 'type': 'file'},
                               'name': 'pop',
                               'type': 'folder'},
                     'name': 'test_pendrive',
                     'type': 'folder'},
           'name': 'media',
           'type': 'folder'}
output2 = {'children': 
                    {'children':
                              {'children': 
                                        {'name': 'paranoid.mp3', 'type': 'file'},
                               'name': 'metal',
                               'type': 'folder'},
                     'name': 'test_pendrive',
                     'type': 'folder'},
           'name': 'media',
           'type': 'folder'}

我的代码现在是这样的:

from collections import defaultdict

l1 = list(output2.items())
l2 = list(output.items())

l3 = l1+l2
d1 = defaultdict(list)
for k,v in l3:
   d1[k].append(v)

它给出了输出:

{
    "name": ["media", "media"],
    "type": ["folder", "folder"],
    "children": [{
            "name": "test_pendrive",
            "type": "folder",
            "children": {
                "name": "dance",
                "type": "folder",
                "children": {
                    "name": "billie_jean.mp3",
                    "type": "file"
                }
            }
        },
        {
            "name": "test_pendrive",
            "type": "folder",
            "children": {
                "name": "pop",
                "type": "folder",
                "children": {
                    "name": "thriller.mp3",
                    "type": "file"
                }
            }
        }
    ]
}

这几乎就是我想要的。我的最终目标是:

{
    "name": ["media", "media"],
    "type": ["folder", "folder"],
    "children": [{
            "name": "test_pendrive",
            "type": "folder",
            "children": [{
                "name": "dance",
                "type": "folder",
                "children": {
                    "name": "billie_jean.mp3",
                    "type": "file"
                }
            },{
                "name": "pop",
                "type": "folder",
                "children": {
                    "name": "thriller.mp3",
                    "type": "file"
                }
            }]
      }
}

我哪里错了?这是实现该目标的最佳方法吗?提前致谢。

【问题讨论】:

  • 你用的是哪个版本的python 3.x+ 还是2.7?
  • 我可能是错的,但是如果有更多的上下文(数据来自哪里,您的最终目标是什么),我认为我们可能能够更好地帮助您。在我看来,您好像在尝试以编程方式重现合并两个文件树的效果。
  • 不清楚你想做什么。例如,在原始树中,“pop”在“test_pendrive”中,而之后不是。但是“舞蹈”确实保留在“test_pendrive”中。为什么他们会受到不同的对待?此外,您的代码将单例放入列表中,而您的输出表明您不想这样做?
  • @TLOwater 我正在使用 Python 3.5.2
  • @strubbly Weel,pop 仍然在 test_pendrive 中。现在,pop 和 dance 作为 test_pendrive 的子项在列表中。

标签: python dictionary


【解决方案1】:

尽管您已经给出了一个明确的示例来说明您想要实现的目标,但这并没有明确说明您的总体目标。例如,您对此有何期望?

output1 = {'children': 
                {'children':
                      {'children': 
                               {'name': 'thriller.mp3', 'type': 'file'},
                           'name': 'pop',
                           'type': 'folder'},
                 'name': 'test_pendrive',
                 'type': 'folder'},
           'name': 'media1',
           'type': 'folder'}
output2 = {'children': 
                {'children':
                      {'children': 
                                {'name': 'paranoid.mp3', 'type': 'file'},
                           'name': 'metal',
                           'type': 'folder'},
                 'name': 'test_pendrive',
                 'type': 'folder'},
       'name': 'media2',
       'type': 'folder'}

哪个是您的示例,但名称已更改?或者这个呢?

output1 = {'children': 
                {'children':
                      {'children': 
                               {'name': 'thriller.mp3', 'type': 'file'},
                           'name': 'pop',
                           'type': 'folder'},
                 'name': 'test_pendrive',
                 'type': 'folder'},
           'name': 'media1',
           'type': 'folder'}
output2 = {'children': 
                {'children':
                      {'children': 
                                {'name': 'paranoid.mp3', 'type': 'file'},
                           'name': 'metal',
                           'type': 'folder'},
                 'type': 'folder'},
       'name': 'media2',
       'type': 'folder'}

这是您的示例,但缺少一个名称。还是这个?

output1 = {'children': 
                {'children':
                      {'children': {} },
           'a': 'b',
           'c': 'd'}
output2 = {'children': 
                {'children':
                      {'children': {"a" : "b"} },
           'a': 'b',
           'c': 'd'}

我已经猜到了您想要做的事情,即合并字典中的值,但在'children' 树结构中递归地执行此操作。这并没有给出您建议的输出,但它可能有意义。

from collections import defaultdict

def merge_children(*dicts):
    result = defaultdict(list)
    for d in dicts:
        for key in d:
            result[key].append(d[key])
    children = result["children"]
    if len(children)>1:
        result["children"] = merge_children(*children)
    return dict(result)

这给出了以下内容:

{'children': 
    {'children': 
        {'children': 
            {'children': [],
             'name': ['thriller.mp3', 'paranoid.mp3'],
             'type': ['file', 'file']
            },
         'name': ['pop', 'metal'],
         'type': ['folder', 'folder']
        },
     'name': ['test_pendrive', 'test_pendrive'],
     'type': ['folder', 'folder']
    },
 'name': ['media', 'media'],
 'type': ['folder', 'folder']
}

或者,也许您也想特别对待'name' 键。在这种情况下,您可能应该使用不同的数据结构来表示您的树 - 如下所示:

output1 = {
 'media' : {'type' : 'folder',
             'children' : {
      'test_pendrive' :
                {'type' : 'folder',
                 'children' : {
          'pop' :
                    {'type': 'folder',
                     'children' :  
                           {'thriller.mp3' : {'type': 'file'},}
                     }}}}}}
output2 = {
 'media' : {'type' : 'folder',
             'children' : {
      'test_pendrive' :
                {'type' : 'folder',
                 'children' : {
          'metal' :
                    {'type': 'folder',
                     'children' :  
                           {'paranoid.mp3' : {'type': 'file'},}
                     }}}}}}

如果您使用这样的结构,那么合并字典确实会合并具有相同名称的子项,因为名称是发生合并的关键。在您的原始版本中不是这种情况。

【讨论】:

  • 这不是我想要的,因为偏执狂被列为流行音乐的孩子,而事实并非如此。
  • 好的,明白你的意思。但是在您的示例中,在顶级字典中,名称被合并,而在较低的目录中则没有。例如,如果 output1 和 output2 中的“名称”不同,会发生什么情况?
  • 我想我没听懂你的意思。名字合并了吗?
猜你喜欢
  • 2020-08-13
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2018-10-16
  • 2021-11-05
  • 2021-04-30
  • 2014-09-04
  • 1970-01-01
相关资源
最近更新 更多