2017-08-25 76 views
1

我有這樣一個低於詞典(但10K鍵 - 值對):搜索元素沒有循環

test_dict={'2*foo*+':['5','10'],'3*bar*-':['15','20']} 

是否有蟒蛇的方式找到的元素,其key.split("*")[0]==2key.split("*")[2]=="+"val[1]<15沒有循環通過字典。它很容易通過for循環來完成,但在我的情況下,這是嵌套到另一個for循環中的較大代碼的一部分,因此完成需要很長時間。

感謝,

+2

最好的性能改進我現在能想到的是要建立另一個詞典,其關鍵字對符合兩個條件'key.split('*')',其值是來自原始'test_dict'字典的對應值的列表,或者如果這是您需要的鍵值對。在你的例子中,你必須將'('2','+')'傳遞給這個新的字典,然後循環遍歷相應的列表並將你的標準應用於該值。表的創建需要一些處理,但是由於它使用散列,訪問會更快。 –

回答

0

可以使用filterset()

test_dict={'2*foo*+':['5','10'],'3*bar*-':['15':'20']} 

possibilities = list(filter(lambda x: int(x[0].split("*")[0]) == 2 and x[0].split("*")[2] == "+" and int(x[1][1]) < 15, test_dict.items())) 
+4

是不是'過濾器'會循環設置? –

+0

打印時返回'[]' – Hrant

+0

@Hrant固定。 'x [0] .split(「*」)[0]'必須作爲'int'輸出。 – Ajax1234

1

至於問,答案是否定的。沒有辦法在不查看每個字典的情況下測試字典的鍵和值,直到找到匹配。

但是,如果你建立一個更復雜的數據結構(可能由一系列類型的字典的),這樣的條目索引由key.split("*")[0],那麼你就只需要遍歷這些元素。

(這聽起來像你想雖然建立一個內存數據庫 - 你很可能會更好只使用一個正確的數據庫,並依託緩存來保留大部分在內存中)

+0

謝謝,很高興知道! – Hrant

0

您注意到「這是嵌套到另一個循環中的更大代碼的一部分」,所以我建議您在外循環之前構建關鍵部分的索引。您的索引將包含與各個條件匹配的密鑰集。因爲它們包含集合,所以您可以找到快速交集來找到滿足您關鍵條件的關鍵字。

from collections import defaultdict 

key_index_num = defaultdict(set) 
key_index_word = defaultdict(set) 
key_index_sign = defaultdict(set) 

for key in test_dict: 
    num, word, sign = key.split('*') 
    key_index_num[num].add(key) 
    key_index_word[word].add(key) 
    key_index_sign[sign].add(key) 

然後,它會很容易找到你的內部循環中的鍵。假設您想要查找所有擁有num == '2'sign == '+'的密鑰。通過做找到鑰匙:

keys = key_index_num['2'].intersection(key_index_sign['+']) 

注:我已經建立了三個指標,但如果你的關鍵的三個部分始終是唯一的,你可以建立一個關鍵指標。然後,該代碼是這樣的:

from collections import defaultdict 

key_index = defaultdict(set) 

for key in test_dict: 
    for key_part in key.split('*'): 
     key_index[key_part].add(key) 

和鍵搜索會是什麼樣子:

keys = key_index['2'].intersection(key_index['+'])