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

时间:2015-05-14 10:17:49

标签: python list dictionary collections counter

我有这样的数据结构:

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

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

在这个例子中,我必须找到并删除secound字典,因为第三个字段具有相同的远程,但是时间戳值较新。

我不熟悉python。我已经搜索了很多,并找到了这样的列表的解决方案:

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

我的问题是,我不够聪明,不能在我的问题上应用这个。此外,该解决方案应该是有效的,因为它必须在具有相当低计算能力的后台作业中永久运行。

谢谢你的帮助!

4 个答案:

答案 0 :(得分:1)

如果你有这个:

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)

答案 1 :(得分:1)

输入:

"1h1h1h"

去除:

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()

答案 2 :(得分:1)

如果您的dicts基于'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上调用下一步以获取最新信息:

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的顺序,因此可能不适合您的问题,如果您的dicts按顺序排列,那么您无需担心排序。

答案 3 :(得分:0)

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}]
相关问题