python - 在 python 字典列表中查找重复项

标签 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"} 字典按键 'un' 的值重复,其次当找到重复项时,我需要决定要保留什么字典关于键 'id' 的第二个值,例如,我们保留具有模式值的字典“厘米”。

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

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 项目进行分类。现在,由于对于字典而言,顺序不是重要因素,因此您需要使用既可散列又不保持其容器顺序的容器。 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'}]
>>> 

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

你可以将列表推导式解释成这样:

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

请注意,由于列表理解的迭代是在 C 中执行的,因此它比常规的 python 循环和 pythonic 方式要快得多。但是如果性能对你来说不重要,你可以使用常规方法。

关于python - 在 python 字典列表中查找重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38621915/

相关文章:

linux - 使用 nohup 在与 ssh 断开连接时帮助运行 python 代码循环

python - 在路由之前修改 flask url

python - Django 管理 session : change default value

python - 如何记录特定时间的音频,直到在Python sounddevice中进行某些操作(如按下键盘)为止?

list - 如何在 swi-prolog 中对最终结果进行排序?(包括谓词)

python - 查找列表和集合之间的差异

python-2.7 - 如何开始在 Python 中分析 XBRL?

python - 如何使 Bokeh 工具栏工具默认处于非事件状态

python 多行注释缩进

Python - 生成父/子字典结构