【问题标题】:How to remove duplicates in a list of dictionaries containing lists?如何删除包含列表的字典列表中的重复项?
【发布时间】:2019-09-18 20:38:44
【问题描述】:

我有一个字典列表,其中每个字典本身都有一个列表:

    [{'author': 'Stephen King', 'books': ['The stand', 'The 
    Outsider']}, {'author': 'Ernest Hemingway', 'books': ['A 
    Moveable Feast', 'The sun Also Rises']},{'author': 'Stephen 
    King', 'books': ['The stand', 'The Outsider']}]

我已经尝试过大多数方法来删除字典列表中的重复项,但到目前为止,由于字典中的数组,它们似乎不起作用。

目的是删除字典列表中的重复项,其中每个字典本身都有一个列表

上述数据中的预期输出应该是:

    [{'author': 'Stephen King', 'books': ['The stand', 'The 
    Outsider']}, {'author': 'Ernest Hemingway', 'books': ['A 
    Moveable Feast', 'The sun Also Rises']}]

【问题讨论】:

  • 我在预期输出中进行了编辑。 @Rakesh
  • 您只关心完全重复的内容(例如,作者姓名和完整的书籍列表都相同)吗?或者,如果书籍列表不匹配,但作者姓名匹配,您是否想做一些不同的事情?
  • @Blckknght 我正在寻找完全相同的副本。

标签: arrays python-3.x dictionary duplicates


【解决方案1】:
dicts = [{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}, {'author': 'Ernest Hemingway', 'books': ['A Moveable Feast', 'The sun Also Rises']},{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}]

def remove(dicts):
    for i in range(len(dicts)):
        if dicts[i] in dicts[i+1:]:
            dicts.remove(dicts[i])
            return remove(dicts)
        else:
            return dicts

print (remove(dicts))

输出:

[{'author': 'Ernest Hemingway', 'books': ['A Moveable Feast', 'The sun Also Rises']}, {'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}]

【讨论】:

  • 当你知道它的索引时从列表中删除一个元素最好使用del dicts[i]而不是索引然后使用remove进行搜索。
  • 嗨,我有一些新的开发,该功能适用​​于 len(list_data) 文件“badger/football.py”,第 16 行,在 remove_dups 返回 remove_dups(dicts) [上一行重复了 993 次以上] 文件“badger/football.py”,第 14 行,在 remove_dups 中如果 dicts[i+1:] 中的 dicts[i]:RecursionError: 超出最大递归深度比较
  • 这是为了避免堆栈溢出。 Python 解释器限制了递归的深度,以帮助您避免无限递归,从而导致堆栈溢出。尝试增加递归限制 (sys.setrecursionlimit) 或在没有递归的情况下重新编写代码。 sys.getrecursionlimit() 返回递归限制的当前值,Python 解释器堆栈的最大深度。此限制可防止无限递归导致 C 堆栈溢出和 Python 崩溃。可以通过 setrecursionlimit() 设置。
  • 完美,非常感谢@ncica ...在 [docs.python.org/3/library/sys.html#sys.setrecursionlimit] 也找到了一篇很棒的文章
【解决方案2】:

这是一种方法。

例如:

data = [{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}, {'author': 'Ernest Hemingway', 'books': ['A Moveable Feast', 'The sun Also Rises']},{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}]

checkVal = set()
result = []
for item in data:
    if item["author"] not in checkVal:   #Check if author & books in checkVal 
        result.append(item)              #Append result.
        checkVal.add(item["author"])     #Add author & books to checkVal 
print(result)

输出:

[{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']},
 {'author': 'Ernest Hemingway',
  'books': ['A Moveable Feast', 'The sun Also Rises']}]

根据评论编辑 -- 检查 authorbooks

checkVal = set()
result = []
for item in data:
    c = tuple(item["books"] + [item["author"]])
    if c not in checkVal:   #Check if author in checkVal 
        result.append(item)              #Append result.
        checkVal.add(c)     #Add author to checkVal 
pprint(result)

【讨论】:

  • 这仅比较作者。如果同一个作者有多个不同书籍列表的词典,则会产生错误的结果。
  • @Blckknght 没错,我接受了它,因为我可以利用这种想法并稍微调整一下
【解决方案3】:

您应该编写一些代码,将您格式中的字典转换为可散列对象。然后正常的重复数据删除代码(使用set)将起作用:

data = [{'author': 'Stephen King', 'books': ['The stand', 'The Outsider']},
        {'author': 'Ernest Hemingway', 'books': ['A Moveable Feast', 'The sun Also Rises']},
        {'author': 'Stephen King', 'books': ['The stand', 'The Outsider']}]

seen = set()
result = []
for dct in data:
    t = (dct['author'], tuple(dct['books'])) # transform into something hashable
    if t not in seen:
        seen.add(t)
        result.append(dct)

此代码假定您的字典只有键 'author''books',没有别的。如果您想要更通用一点并支持其他键和值,您可以稍微扩展逻辑。这是t 的另一种计算,它支持任意键(只要它们都是可比较的)和值中的任意数量的列表:

t = tuple((k, tuple(v) if insinstance(v, list) else v) for k, v in sorted(dct.items())

【讨论】:

    猜你喜欢
    • 2013-10-29
    • 2017-08-13
    • 2012-02-16
    • 1970-01-01
    • 2018-05-13
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多