【问题标题】:Find duplicates in python list of dictionaries在python字典列表中查找重复项
【发布时间】:2021-11-17 07:39:45
【问题描述】:

我在下面有一本字典:

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' 键查找字典的重复项,例如 this {'un': 'a', 'id': "cd"} 和 this {'un': 'a', 'id ':“cm”} dicts 是键 'un' 的值的重复项,其次当发现重复项时,我需要决定保留哪个 dict 来保留键 'id' 的第二个值,例如,我们将 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 保留和什么省略。非常感谢您的帮助。

【问题讨论】:

  • 您需要为此使用字典列表吗?数据框可能更适合此类任务
  • 您是要查找它们自己键的重复项还是['un'] 处的值的重复项?
  • 重复值
  • 我在 dicts 列表中获取 tis 数据,如果未来会尝试 hanks 的建议!
  • dict 是用于创建字典的内置 python 命令,因此您可能希望避免将其用作变量名。

标签: python list python-2.7 dictionary


【解决方案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'}]
>>> 

在最后一行(嵌套列表理解)中,我们循环遍历聚合字典的项目,然后遍历值,并将这些项目保持在后面的值或 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 循环和 Python 的方式要快得多。但是,如果性能对您不重要,您可以使用常规方法。

【讨论】:

  • 你能简单解释一下你最后的一个班轮吗?
【解决方案2】:

使用 defaultdict,您几乎走上了正确的轨道……这就是我的大致写法。

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

【讨论】:

    【解决方案3】:

    以前的答案不适用于字典有两个以上项目的列表(即它们最多只保留两个键值对 - 如果想要保留所有键值对怎么办? ,但删除重复特定键的那些?)

    为避免将新项目添加到字典列表其中一个特定键重复,您可以这样做:

    import pandas as pd
    
    all = [
        {"email":"art@art.com", "dn":"Art", "pid":11293849},
        {"email":"bob@bob.com", "dn":"Bob", "pid":12973129},
        {"email":"art@art.com", "dn":"Art", "pid":43975349},
        {"email":"sam@sam.com", "dn":"Sam", "pid":92379234},
    ]
    
    df = pd.DataFrame(all)
    df.drop_duplicates(subset=['email'], keep='last', inplace=True)
    all = df.to_dict("records")
    print(all)
    

    【讨论】:

      猜你喜欢
      • 2019-01-15
      • 2013-07-06
      • 2013-02-12
      • 2013-10-01
      • 2022-01-22
      • 2023-01-07
      • 1970-01-01
      • 2021-12-14
      相关资源
      最近更新 更多