如何在列表中移除唯一和重复的字典?

3 投票
7 回答
673 浏览
提问于 2025-04-15 15:57

给定一个包含一些重复字典和一些独特字典的列表,最好的方法是什么来先移除独特字典,然后将重复字典减少到只保留一个实例?我得说,我最近才开始接触Python,但它让这个项目简单多了。我只是对这种问题有点困惑。

所以我的列表看起来是这样的:

[{  'file': u'/file.txt',
    'line': u'line 666',
    'rule': u'A DUPLICATE RULE'}

{   'file': u'/file.txt',
    'line': u'line 666',
    'rule': u'A DUPLICATE RULE'}

{   'file': u'/uniquefile.txt',
    'line': u'line 999',
    'rule': u'A UNIQUE RULE'}]

我想要的最终结果是,列表应该看起来像这样:

[{  'file': u'/file.txt',
    'line': u'line 666',
    'rule': u'A DUPLICATE RULE'}]

7 个回答

1
>>> import itertools
>>> list(a[0] for a in itertools.groupby(sorted(data)) if len(list(a[1])) > 1)
[{'file': u'/file.txt', 'line': u'line 666', 'rule': u'A DUPLICATE RULE'}]

检查这个问题可能有比用 len(list(a[1])) 更好的方法。

补充说明:我加了一次对排序的调用。

2

我总是喜欢用对象来工作,而不是用字典,特别是当每个项目的字段都一样的时候。

所以,我定义了一个类:

class rule(object):
    def __init__(self, file, line, rule):
        self.file = file
        self.line = line
        self.rule = rule

    #Not a "magic" method, just a helper for all the methods below :)
    def _tuple_(self):
        return (self.file, self.line, self.rule)

    def __eq__(self, other):
        return cmp(self, other) == 0

    def __cmp__(self, other):
        return cmp(self._tuple_(), rule._tuple_(other))

    def __hash__(self):
        return hash(self._tuple_())

    def __repr__(self):
        return repr(self._tuple_())

接下来,创建一个这些对象的列表,并对它进行排序。ruledict_list可以作为你问题中的示例数据。

rules = [rule(**r) for r in ruledict_list]
rules.sort()

然后,遍历这个(已排序的)列表,逐个去掉唯一的对象。最后,创建一个集合来去除重复项。这个循环也会去掉每个重复对象中的一个,但这其实没什么大不了的。

pos = 0
while(pos < len(rules)):
    while pos < len(rules)-1 and rules[pos] == rules[pos+1]:
        print "Skipping rule %s" % rules[pos]
        pos+=1
    rules.pop(pos)
rule_set = set(rules)
4

一个想法是对数据进行排序。假设 inputdata 是你上面提到的列表:

from itertools import groupby
from operator import itemgetter

inputdata.sort(key=itemgetter(*inputdata[0])) # ensures order
print [k for k, g in groupby(inputdata) if len(list(g)) > 1]

输出结果是:

[{'line': u'line 666', 'file': u'/file.txt', 'rule': u'A DUPLICATE RULE'}]

撰写回答