[英]QUICKEST way to find a key in a dictionary
我有一本字典,有超過 1100 萬個鍵(每個值都是一個列表)。每個鍵都是一個唯一的整數。
例如
Dict1 = {11:"a",12:"b",22:"c",56:"d"}
然后,分別地,我有一個范圍列表,例如 [10-20,30-40,50-60]
我想說,對於我的范圍列表中的每個范圍,如果鍵在該范圍內,則遍歷字典並返回值。
所以它會返回:
10-20: "a","b"
50-60: "d"
我使用的實際代碼是:
for each_key in sorted(dictionary):
if each_key in range(start,end):
print str(dictionary[each_key])
問題是這種技術太長了,因為它要遍歷所有 1100 萬個鍵並檢查它是否在范圍內。
有沒有一種方法可以說“跳過所有字典鍵,直到找到一個高於起始編號”,然后“一旦結束編號高於鍵就停止”? 基本上只是某種方式,可以非常快速地放大一定范圍內的字典部分?
謝謝
只需使用 Python 的 EAFP 原理即可。 請求寬恕比獲得許可更容易。
假設所有鍵都有效,如果不是,則捕獲錯誤:
for key in xrange(start, end):
try:
print str(dictionary[key])
except KeyError:
pass
這將只是嘗試將每個數字作為鍵,如果存在來自不存在的鍵的KeyError
,那么它將繼續進行下一次迭代。
請注意,如果您預計會丟失很多鍵,那么先進行測試可能會更快:
for key in xrange(start, end):
if key in dictionary:
print str(dictionary[key])
請注意, xrange
只是一個與range
略有不同的函數。 它將一個一個地生成值,而不是提前創建整個列表。 在 for 循環中使用很有用,在這種情況下沒有缺點。
我對這個問題的想法是首先找到正確的密鑰。 您的解決方案花費太多時間的原因是它使用 O(n) 算法來找到正確的密鑰。 如果我們可以實現二分查找方法,復雜度會降低到O(log(n)),這很有幫助。
以下是我的示例代碼。 它適用於示例,但我不能保證它不會出現一些小錯誤。 只需在那里找到想法並實施您的想法即可。
def binarySearch(alist, target):
left = 0
right = len(alist) -1
if target>alist[-1]:
return len(alist)
while left < right:
m = (left + right) / 2
if alist[m] == target:
return m
if alist[m] < target:
left = m+1
else:
right = m
return left
def work(dictionary, start, end):
keys = sorted(dictionary.keys())
start_pos = binarySearch(keys, start)
end_pos = binarySearch(keys, end)
print [dictionary[keys[pos]] for pos in range(start_pos,end_pos)]
dictionary = {11:"a",12:"b",22:"c",56:"d"}
work(dictionary, 10, 20)
work(dictionary, 20, 40)
work(dictionary, 10, 60)
這個解決方案(使用 OrderedDict 和 filter )可以幫助你一點。
from collections import OrderedDict
d = {2:3, 10:89, 4:5, 23:0}
od = OrderedDict(sorted(d.items()))
lst=["1-10","11-20","21-30"]
lower_lst=map(int,[i.split("-")[0] for i in lst])
upper_lst=map(int,[i.split("-")[1] for i in lst])
for low,up in zip(lower_lst,upper_lst):
print "In range {0}-{1}".format(low,up),filter(lambda a:low <= a[0] <= up,od.iteritems())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.