在python词典列表中查找重复项

时间:2016-07-27 19:46:22

标签: python list python-2.7 dictionary

我的词典如下:

a = [{'un': 'a', 'id': "cd"}, {'un': 'b', 'id': "cd"},{'un': 'b', 'id':    "cd"}, {'un': 'c', 'id': "vd"},
    {'un': 'c', 'id': "a"}, {'un': 'c', 'id': "vd"}, {'un': 'a', 'id': "cm"}]

我需要通过'un'键找到字典的副本,例如这个{'un':'a','id':“cd”}和这个{'un':'a','id ':“cm”} dicts与键'un'的值重复第二,当找到重复项时我需要决定关于键'id'的第二个值的dict保持什么,例如我们保持dict的模式值“厘米”。

我已经做了第一步看到下面的代码:

from collections import defaultdict
temp_ids = []
dup_dict = defaultdict(list)
for number, row  in enumerate(a):
    id = row['un']
    if id not in temp_ids:
        temp_ids.append(id)
    else:
        tally[id].append(number)

使用此代码我或多或少能够找到重复列表的索引,也许还有其他方法可以做到这一点。而且我还需要下一步代码来决定dict保留什么以及省略什么。将非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

一般情况下,如果要在字典列表中查找重复项,则应按照重复字典保留在同一组中的方式对字典进行分类。为此,您需要根据dict项目进行分类。现在,因为对于字典,订单不是一个重要的因素,您需要使用既可以清洗又不保持其容器顺序的容器。 frozenset()是此任务的最佳选择。

示例:

In [87]: lst = [{2: 4, 6: 0},{20: 41, 60: 88},{5: 10, 2: 4, 6: 0},{20: 41, 60: 88},{2: 4, 6: 0}]

In [88]: result = defaultdict(list)

In [89]: for i, d in enumerate(lst):
    ...:     result[frozenset(d.items())].append(i)
    ...:     
In [91]: result
Out[91]: 
defaultdict(list,
            {frozenset({(2, 4), (6, 0)}): [0, 4],
             frozenset({(20, 41), (60, 88)}): [1, 3],
             frozenset({(2, 4), (5, 10), (6, 0)}): [2]})

在这种情况下,您可以根据'un'键对词典进行分类,然后根据id选择预期的项目:

>>> from collections import defaultdict
>>> 
>>> d = defaultdict(list)
>>> 
>>> for i in a:
...     d[i['un']].append(i)
... 
>>> d
defaultdict(<type 'list'>, {'a': [{'un': 'a', 'id': 'cd'}, {'un': 'a', 'id': 'cm'}], 'c': [{'un': 'c', 'id': 'vd'}, {'un': 'c', 'id': 'a'}, {'un': 'c', 'id': 'vd'}], 'b': [{'un': 'b', 'id': 'cd'}, {'un': 'b', 'id': 'cd'}]})
>>> 
>>> keeps = {'a': 'cm', 'b':'cd', 'c':'vd'} # the key is 'un' and the value is 'id' should be keep for that 'un'
>>> 
>>> [i for key, val in d.items() for i in val if i['id']==keeps[key]]
[{'un': 'a', 'id': 'cm'}, {'un': 'c', 'id': 'vd'}, {'un': 'c', 'id': 'vd'}, {'un': 'b', 'id': 'cd'}, {'un': 'b', 'id': 'cd'}]
>>> 

在最后一行(嵌套列表推导)中,我们遍历聚合的dict项目,然后遍历值,并将这些项目保留在后面的值或条件i['id']==keeps[key]中,这意味着我们将在id词典中保留keeps具有指定值的项目。

你可以将列表理解放在这样的东西上:

final_list = []
for key, val in d.items():
    for i in val:
        if i['id']==keeps[key]:
             final_list.append(i)

请注意,由于列表推导的迭代已在C中执行,因此它比常规python循环和pythonic方式更快。但如果性能对您不重要,您可以使用常规方法。

答案 1 :(得分:1)

你几乎在正确的轨道上有一个默认的...这里大概是我会怎么写的。

from collections import defaultdict
a = [{'un': 'a', 'id': "cd"}, {'un': 'b', 'id': "cd"},{'un': 'b', 'id':    "cd"}, {'un': 'c', 'id': "vd"}, {'un': 'c', 'id': "a"}, {'un': 'c', 'id': "vd"}, {'un': 'a', 'id': "cm"}]

items = defaultdict(list)
for row in a:
    items[row['un']].append(row['id'])  #make a list of 'id' values for each 'un' key

for key in items.keys():
    if len(items[key]) > 1:  #if there is more than one 'id'
        newValue = somefunc(items[key])  #decided which of the list items to keep
        items[key] = newValue  #put that new value back into the dictionary