2016-05-13 58 views
0

我有一個這樣類型的字典列表(可能有雖然高達12000項):獲取類型的字典列表僅第一副本與Python

[ 
{'date': datetime.datetime(2016, 1, 31, 0, 0), 'title': 'Entry'}, 
{'date': datetime.datetime(2016, 1, 11, 0, 0), 'title': 'Something'}, 
{'date': datetime.datetime(2016, 1, 01, 0, 0), 'title': 'Entry'} 
] 

的第一項是最新的。我想刪除具有相同標題的複製品,但保留最老的複製品。

+2

爲什麼類型的字典列表?爲什麼不把一個大字典作爲關鍵字和日期作爲值?那麼它本質上不能有任何重複。 –

+0

我以前沒有使用python,必須從網站上抓取數據。我只是偶然地用一個方法列出了一些詞典。所以沒有具體的原因我自己 – Sannin

回答

1

我認爲這是做你想做的,但我也使用字典而不是列表。這似乎更適合這種類型的數據:

import datetime 

dict_list = [ 
    {'date': datetime.datetime(2016, 1, 31, 0, 0), 'title': 'Entry'}, 
    {'date': datetime.datetime(2016, 1, 11, 0, 0), 'title': 'Something'}, 
    {'date': datetime.datetime(2016, 1, 01, 0, 0), 'title': 'Entry'} 
] 

dict_keys = set(map(lambda x: x["title"], dict_list)) 

earliest_entries = {k:min(x["date"] for x in dict_list if x["title"] == k) for k in dict_keys} 

輸出:

>>> earliest_entries 
{'Entry': datetime.datetime(2016, 1, 1, 0, 0), 'Something': datetime.datetime(2016, 1, 11, 0, 0)} 
>>> 
2

如果你想保持它在格式列表中,那麼你可以只保留一個seenset獨特的遊戲,並辦理列表或者刪除條目或添加到seen

def r_enumerate(iterable): 
    #use itertools.izip and xrange if you are using python 2! 
    return zip(reversed(range(len(iterable))), 
       reversed(iterable)) 

seen = set() 
for i, subdata in r_enumerate(data): 
    if subdata['title'] in seen: 
     del data[i] 
    else: 
     seen.add(subdata['title']) 

這億韓元不修改數據的順序,向後移動意味着後面的(舊的)條目被保留,並且因爲你正在向後移動它,所以你不必擔心刪除掉迭代剩餘部分的項目。


在另一方面,如果你願意用字典來存儲所有的入口,而不是小詞典,這是真正的名單,很容易:

{partdict['title']: partdict['date'] for partdict in LIST_OF_DICTS} 

當評估條目稍後在列表中將覆蓋以前的內容,因此這將只保留最早的條目,更不用說您可以通過標題而不是列表中的位置來索引條目。

要返回到列表格式(但只包含每個名稱的最老的項目),你可以這樣做:

[{'title':title, 'date':date} for title,date in DICT_FORM] 

雖然這會搞亂秩序,如果你有更多的工作首先要以這種格式留下它。

+0

謝謝你的幫助。我已經使用jDo的解決方案,因爲它似乎是我的代碼中最容易採用的。數據的順序對我來說並不重要。我只是認爲,如果知道最後一個(或第一個帶有反向列表)標題是要保留的標題,它會更容易。當我得到數據時,列表已經排序。 – Sannin

+0

如果您使用jDo的答案,您爲什麼不接受它? –

+0

我忘了。謝謝你提醒我。 – Sannin

相關問題