【问题标题】:Python 2.7: Replace duplicates in a list of dictionaries [closed]Python 2.7:替换字典列表中的重复项[关闭]
【发布时间】:2026-01-10 03:10:01
【问题描述】:

我有一个字典列表:

l = [{u'content': [], u'name': u'child_01'}, {u'content': [], u'name': u'child_01'} ,{u'content': [], u'name': u'child_04'}]

我想检测重复并用

替换它们
{u'content': [], u'name': u'child'}

set 不适用于字典。

【问题讨论】:

  • 示例中列表的输出应该是什么?
  • 仅基于u'name' 的重复项?
  • 键相同但值不同的条目怎么办?两者不能存储在同一个字典中。
  • 1.在输出中,我需要将其中一个重复的字典替换为另一个。 2. 是的,基于 u'name'。 3.我不能换字典

标签: python python-2.7 list dictionary


【解决方案1】:

嗯,这不是完整的答案,但也许它会给你一些提示,你可以执行以下操作:

l = [{u'content': [], u'name': u'child_01'}, {u'content': [], u'name': u'child_01'} ,{u'content': [], u'name': u'child_04'}]

from itertools import groupby
uniques = [key for key, value in groupby(l)]

您遇到的问题是字典不可散列,因此您无法调用set()。现在,我知道这个解决方案没有插入:

{u'content': [], u'name': u'child'}

对于重复项,但是当您为每个重复项插入它们时,您将创建另一个重复项,所以也许可以这样做。首先,将列表缩减为只有唯一值,然后比较列表的长度(缩减前后),并根据需要添加任意数量的“默认”字典,如下所示:

defaults_cnt = len(l) - len(uniques)
default = {u'content': [], u'name': u'child'}
uniques.extend(default for _ in xrange(defaults_cnt))

现在:

from pprint import pprint
pprint(uniques)
[{'content': [], 'name': 'child_01'},
 {'content': [], 'name': 'child_04'},
 {'content': [], 'name': 'child'}]

【讨论】:

  • 解决了问题。
【解决方案2】:

您可以定义一个类 Entry,它是 dict 的子类,并将其设为 hashable

class Entry(dict):
    def __init__(self, *args, **kwargs):
        super(Entry, self).__init__(*args, **kwargs)
        self['name'] = self['name'].split('_')[0]

    def __hash__(self):
        return hash(self['name'])

    def __eq__(self, other):
        if isinstance(other, Entry):
            return self['name'] == other['name']
        return NotImplemented

    def __ne__(self, other):
        return not self == other

name 属性在构造函数中被规范化以删除数字后缀。

要将此类与set 一起使用,您还需要定义__eq____ne__ 运算符。

您可以像这样使用此类来删除重复项:

l = [{u'content': [], u'name': u'child_01'},
     {u'content': [], u'name': u'child_01'},
     {u'content': [], u'name': u'child_04'}]

entries = set(Entry(attrs) for attrs in l)

print(entries)

你得到一组一个字典:

{{'name': 'child', 'content': []}}

【讨论】: