【问题标题】:Remove dict which have the same id from a list of dict从 dict 列表中删除具有相同 id 的 dict
【发布时间】:2020-03-14 01:37:24
【问题描述】:

我想从字典列表中删除具有相同 ID 的字典。

def removeDuplicate(elems, id):
    new_list = []
    for elem in elems:
        if not elem[id] in [d[id] for d in new_list if id in d]:
            new_list.append(elem)
    return new_list


a = [
    {0 : 'a', 'id' : 2, 2 : 'c', time : '1'},
    {0 : 'a', 'id' : 2, 2 : 'c', time : '2'},
    {0 : 'a', 'id' : 3, 2 : 'c', time : '3'},
    {0 : 'a', 'id' : 4, 2 : 'c', time : '4'},
    {0 : 'a', 'id' : 5, 2 : 'c', time : '5'},
    {0 : 'a', 'id' : 4, 2 : 'c', time : '6'},
    {0 : 'a', 'id' : 2, 2 : 'c', time : '7'},
    {0 : 'a', 'id' : 3, 2 : 'c', time : '8'},
]
print(a)

a = removeDuplicate(a, 'id')

print(a)

7000 个元素可以正常工作,但 500 000 个元素需要很长时间。

有没有更好的方法来删除这些事件?

【问题讨论】:

  • 您每次都在一次又一次地生成 ID 列表,即使它没有改变。在循环之前执行一次。更好的是,把它做成一套。
  • The if id in d` 检查列表理解是不必要的,因为通过构造,所有元素都必须有一个 id 字段。
  • 好问题 Alexall!请看我的回答,你通常应该避免隐藏内置函数或保留关键字。

标签: python python-3.x list dictionary nested


【解决方案1】:

在进行查找时尝试使用set,因为它只有 O(1) 复杂度。也尽量不要在不必要的时候循环。

你的这个稍微修改过的代码应该足够快,即使是 50 万个元素

def removeDuplicate(elems, id):
    new_list = []
    read_ids = set()
    for elem in elems:
        if elem[id] not in read_ids:
            read_ids.add(elem[id])
            new_list.append(elem)
    return new_list

【讨论】:

  • elem[id] not in read_ids 的风格要好一些,尤其是因为它应该是指not (elem[id] in read_ids) 还是(not elem[id]) in read_ids
【解决方案2】:

您的代码的复杂度为 O(n^2)(甚至更糟)。你不断地重新创建和重复new_list

只需将您已经看到的所有 id 设置为一组。 in 签入 set 是一个 O(1) 操作。

def removeDuplicate(elems, id):
    seen_ids = set()
    new_list = []
    for elem in elems:
        if elem[id] not in seen_ids:
            new_list.append(elem)
            seen_ids.add(elem[id])
    return new_list


a = [
    {0 : 'a', 'id' : 2, 2 : 'c', time : '1'},
    {0 : 'a', 'id' : 2, 2 : 'c', time : '2'},
    {0 : 'a', 'id' : 3, 2 : 'c', time : '3'},
    {0 : 'a', 'id' : 4, 2 : 'c', time : '4'},
    {0 : 'a', 'id' : 5, 2 : 'c', time : '5'},
    {0 : 'a', 'id' : 4, 2 : 'c', time : '6'},
    {0 : 'a', 'id' : 2, 2 : 'c', time : '7'},
    {0 : 'a', 'id' : 3, 2 : 'c', time : '8'},
]
print(a)

a = removeDuplicate(a, 'id')

print(a)

【讨论】:

  • 请不要隐藏内置插件,请参阅我的回答。
【解决方案3】:

请不要将参数/变量命名为id,它是内置的 (https://docs.python.org/3/library/functions.html#id)。

def remove_duplicate(elems, k):
    new_list = []
    seen_keys = set()
    for elem in elems:
        if elem[k] not in seen_keys:
            new_list.append(elem)
            seen_keys.add(k)
    return new_list

【讨论】:

  • 他可以覆盖它,只要他知道自己在做什么并且不需要内置函数。我可能会出于命名清晰的目的这样做。
【解决方案4】:

你可以这样做:


def removeDuplicate(elems, id):
    new_list = []
    ids = {e[id] for e in elems}
    for elem in elems:
        if elem[id] in ids:
            new_list.append(elem)
            ids.remove(elem[id])
    return new_list

【讨论】:

  • 请不要隐藏内置插件,请参阅我的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多