2015-05-14 68 views
1

我有這樣的一個數據結構:如何刪除重複的條目在嵌套容器

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

詞典列表。我的任務是找到有關遠程值的重複條目。如果我發現具有相同遠程值的條目比我想刪除除最新時間戳值之外的所有條目都要多。

在此示例中,我必須找到並刪除secound字典,因爲第三個字典具有相同的遠程,但具有較新的時間戳值。

Iam不太熟悉python。我已經很多一派,發現名單公正的解決辦法是這樣的:

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

我的問題是,是的IAM不夠聰明,我的問題,應用此。此外,解決方案應該有點高效,因爲它必須在計算能力相當低的背景工作中永久運行。

謝謝你的幫忙!

+0

才能添加您的預期了把你的代碼,您到目前爲止試過嗎? – Kasramvd

+0

是每個字典中的關鍵字,並且是排序順序的字典嗎? –

回答

1

輸入:

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}] 
+0

工作正常。謝謝! – user3394244

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) 
+0

您的代碼無法按預期工作。見https://ideone.com/kHGvFn – Alik

+0

它現在的作品,但我認爲斯蒂芬Pochmann的解決方案比我的效率更高 – BurningKarl

+0

upvote it :) – Alik

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以獲得最新的:

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是像你的輸入那樣,那麼你不必擔心排序問題。

+0

@JoseRicardoBustosM。我雖然兩把鑰匙都必須搭配纔算是笨蛋,但它只是遙控鑰匙。 –

+1

是的,我現在明白了......謝謝 –

+0

@JoseRicardoBustosM。別擔心。 –

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}] 

排序的基於時間戳和因爲你需要最新的(最大),相反是真的

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}]