如何删除嵌套容器中的重复条目

How to delete duplicate entries in a nested container

我有这样的数据结构:

[{'remote': '1', 'quantity': 1.0, 'timestamp': 1}, 
{'remote': '2', 'quantity': 1.0, 'timestamp': 2},
{'remote': '2', 'quantity': 1.0, 'timestamp': 3}, ...]

词典列表。我的任务是找到关于远程值的重复条目。如果我发现具有相同远程值的条目比我想删除除具有最新时间戳值的条目之外的所有条目。

在这个例子中,我必须找到并删除第二个字典,因为第三个字典具有相同的遥控器,但时间戳值较新。

我对 python 不是很熟悉。我在谷歌上搜索了很多,只找到了像这样的列表的解决方案:

How can I count the occurrences of a list item in Python?

我的问题是,我不够聪明,无法将此应用到我的问题上。此外,该解决方案应该有点高效,因为它必须 运行 永久地处于计算能力相当低的后台作业中。

感谢您的帮助!

如果你有这个:

data = [{"remote":1, "quantity":1.0, "timestamp":1},
        {"remote":2, "quantity":1.0, "timestamp":2},
        {"remote":2, "quantity":1.0, "timestamp":3}]

您可以像这样过滤条目:

filtered_data = []
for d1 in sorted(data, key=lambda e: e["timestamp"], reverse=True):
    for d2 in filtered_data:
        if d1["remote"] == d2["remote"]:
            break
    else:
        filtered_data.append(d1)

输入:

entries = [{'remote': '1', 'quantity': 1.0, 'timestamp': 1},
           {'remote': '2', 'quantity': 1.0, 'timestamp': 2},
           {'remote': '2', 'quantity': 1.0, 'timestamp': 3}]

删除:

newest = {}
for entry in entries:
    current = newest.get(entry['remote'])
    if current is None or entry['timestamp'] > current['timestamp']:
        newest[entry['remote']] = entry
entries[:] = newest.values()

输出:

from pprint import pprint
pprint(entries)

Prints:
[{'quantity': 1.0, 'remote': '2', 'timestamp': 3},
 {'quantity': 1.0, 'remote': '1', 'timestamp': 1}]

如果您的字典是根据 'remote' 键排序的,您可以按 'remote' 键对它们进行分组并获取最后一个条目,这将是最新的时间戳。

l = [{'remote': '1', 'quantity': 1.0, 'timestamp': 1},
{'remote': '2', 'quantity': 1.0, 'timestamp': 2},
{'remote': '2', 'quantity': 1.0, 'timestamp': 3}]


from itertools import groupby
from operator import itemgetter

l[:] = (list(v)[-1] for _, v in groupby(l,key=(itemgetter("remote"))))

print(l)
[{'timestamp': 1, 'remote': '1', 'quantity': 1.0},
 {'timestamp': 3, 'remote': '2', 'quantity': 1.0}]

l[:] 更改原始列表,(list(v)[-1] for k,v in groupby(l,key=(itemgetter("remote")))) 是一个生成器表达式,这意味着我们不需要一次将所有内容存储在内存中,如果内存也是一个问题,这将有所帮助。

这也适用于未排序的数据,一旦被骗者总是在一起并且最新的被骗者排在最后:

l = [{'remote': '1', 'quantity': 1.0, 'timestamp': 1},
           {'remote': '4', 'quantity': 1.0, 'timestamp': 1},
           {'remote': '2', 'quantity': 1.0, 'timestamp': 2},
           {'remote': '2', 'quantity': 1.0, 'timestamp': 3}]

l[:] = (list(v)[-1] for k,v in groupby(l, key=(itemgetter("remote"))))

print(l)
[{'timestamp': 1, 'remote': '1', 'quantity': 1.0}, {'timestamp': 1, 'remote': '4', 'quantity': 1.0}, {'timestamp': 3, 'remote': '2', 'quantity': 1.0}]

或者,如果重复对象未排序,则根据时间戳获取最大值:

l = [{'remote': '1', 'quantity': 1.0, 'timestamp': 1},
           {'remote': '4', 'quantity': 1.0, 'timestamp': 1},
           {'remote': '2', 'quantity': 1.0, 'timestamp': 3},
           {'remote': '2', 'quantity': 1.0, 'timestamp': 2}]

l[:] = (max(v,key=itemgetter("timestamp")) for _, v in groupby(l, key=(itemgetter("remote")))


[{'timestamp': 1, 'remote': '1', 'quantity': 1.0}, {'timestamp': 1, 'remote': '4', 'quantity': 1.0}, {'timestamp': 3, 'remote': '2', 'quantity': 1.0}]

如果您要排序,您应该通过远程键进行就地反向排序,他们在分组 v 上调用 next 以获取最新的:

l = [{'remote': '1', 'quantity': 1.0, 'timestamp': 1},
           {'remote': '4', 'quantity': 1.0, 'timestamp': 1},
           {'remote': '2', 'quantity': 1.0, 'timestamp': 3},
           {'remote': '2', 'quantity': 1.0, 'timestamp': 2}]

l.sort(key=itemgetter("remote"),reverse=True)
l[:] = (next(v) for _, v in groupby(l, key=(itemgetter("remote"))))

print(l)

排序会改变字典的顺序,所以这可能不适合您的问题,如果您的 dicts 与您的输入一样有序,那么您无论如何都不需要担心排序。

In [55]: from itertools import groupby

In [56]: from operator import itemgetter


In [58]: a
Out[58]: 
[{'quantity': 1.0, 'remote': '1', 'timestamp': 1},
 {'quantity': 1.0, 'remote': '2', 'timestamp': 2},
 {'quantity': 1.0, 'remote': '2', 'timestamp': 3}]

根据时间戳对 a 进行了排序,因为您需要最新的(最大的),所以倒序为真

In [58]: s_a=sorted(a,key=lambda x: x['timestamp'],reverse = True)
In [59]: groups=[]
In [60]:for k,g in groupby(s_a,key=lambda x:x['remote']):
    groups.append(list(g))
In [69]: [elem[0] for elem in groups]
Out[69]: 
[{'quantity': 1.0, 'remote': '2', 'timestamp': 3},
 {'quantity': 1.0, 'remote': '1', 'timestamp': 1}]