2013-02-15 51 views
0

查一查字典蟒值我有了鑰匙Unix紀元時間戳,像這樣一個字典:通過表達

lookup_dict = { 
    1357899: {} #some dict of data 
    1357910: {} #some other dict of data 
} 

除此之外,你知道,參賽的數以百萬計和數以百萬計。我想重複這個詞典,一遍又一遍。理想情況下,我很樂意能寫的東西像我可以在R,像:

lookup_value = 1357900 
dict_subset = lookup_dict[key >= lookup_value] 
# dict_subset now contains {1357910: {}} 

但我承認,我找不到任何實際證明,這是Python的東西,而不必能做的,一個方式或其他,遍歷每一行。如果我正確地理解了Python(並且我可能不),key in dict表格的密鑰查找使用二進制搜索,因此速度非常快;任何方式來執行二進制搜索,在字典鍵?

+0

密鑰是唯一的,並有一個相應的值。他們要麼在字典中,要麼不在字典中。我不明白這個問題。 – NullUserException 2013-02-15 00:48:49

+2

鍵被散列 - 不在btrees中。所以,也許你想看看'bisect'模塊將列表作爲關鍵字,並將字典列表作爲相應的值 - 並在找到合適的索引後使用切片.... – 2013-02-15 00:52:04

+0

@JonClements:這是有效的,但我建議使用包裝'bisect'的兩個'sortedlist'食譜中的一個(或者可能不是,就像'blist'中的那個'),因爲基於「基於二分法」代碼很難閱讀,並且容易出錯。 – abarnert 2013-02-15 01:09:14

回答

2

要做到這一點而不進行迭代,您將需要排序順序的鍵。那麼你只需要對第一個>= lookup_value進行二分搜索,而不是檢查每個搜索的>= lookup_value

如果你願意使用第三方庫,那裏有很多。前兩個想到的是bintrees(使用紅黑樹,如C++,Java等)和blist(使用B +樹)。例如,對於bintrees,它是如此簡單:

dict_subset = lookup_dict[lookup_value:] 

,這將被視爲有效,你倒是希望,基本上,它增加了使用該子集的不惜一切代價的上方設置了一個O(log N)搜索。 (當然,通常你想對這個子集做的事情是迭代整個事情,無論如何它最終會成爲O(N)......但是也許你正在做一些不同的事情,或者這個子集只有1000000箇中的10個鍵。)

當然有一個權衡。隨機訪問基於樹的映射是O(log N)而不是「通常O(1)」。此外,您的密鑰顯然需要完全訂購,而不是可哈希(並且很難自動檢測並提出好的錯誤消息)。

如果你想自己建立這個,你可以。你甚至不一定需要一棵樹;只是排序list的鍵旁邊dict。正如JonClements建議的那樣,您可以使用stdlib中的bisect模塊來維護list。您可能想要包裝bisect以創建一個排序列表對象,或者更好的方法是獲取ActiveState或PyPI上的一個配方來爲您做。然後,您可以將排序列表和dict組合到一個對象中,這樣您就不會意外更新其中一個而不更新其他對象。如果你願意的話,你可以將接口擴展到bintrees

+0

廢話。謝謝!這......非常好,正是我想知道的。正如你正確地認識到的那樣(儘管我,呃,在我的問題中可能沒有說清楚),我們的目標是取一組〜200M行,並在單個數字中包含一個子集,查找結果是.. 。 複雜。但它使我非常樂意使用第三方庫;我會看看'bintrees'。非常感謝! – Gastove 2013-02-16 01:41:08

0

使用下面的代碼將制定出

some_time_to_filter_for = # blah unix time 
# Create a new sub-dictionary 
sub_dict = {key: val for key, val in lookup_dict.items() 
      if key >= some_time_to_filter_for} 

基本上我們只是通過在你的字典裏所有鍵進行迭代,並給出一個時間過濾掉了,我們要把一切都大於或等於鍵值並將它們放入我們的新詞典中

+0

問題是「如何不迭代」。另外,不要使用'items()'。 – wRAR 2013-02-15 01:02:15

+1

'items()'在python 3上是可以的 – wim 2013-02-15 01:07:43

+0

@wim我知道,但我仍然認爲Python 2的所有用法應該明確地標記爲這樣。 – wRAR 2013-02-15 01:29:12