簡體   English   中英

在字典中查找鍵的最快方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM