如何在列表中移除唯一和重复的字典?
给定一个包含一些重复字典和一些独特字典的列表,最好的方法是什么来先移除独特字典,然后将重复字典减少到只保留一个实例?我得说,我最近才开始接触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'}]