簡體   English   中英

從字典中的列表中查找元素,然后返回該鍵

[英]Find an element from a list in a dictionary and return that key

如果我將someDictionary定義為

{'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}

someList定義為

[51, 52, 53, 54, 55, 56]

如何在someDictionary中找到與someDictionary中的元素匹配的someList 現在,我假設不會有超過一場比賽。

我認為應該是這樣的:

for k, v in someDictionary.items():
    if v == someList:
        myAnswer = k

鑒於以上代碼, myAnswer3

第二部分我需要做的是,如果someList不包含在一個元素someDictionary ,找到在價值someDictionary大於(但最接近)在someList的最后一個元素someList[-1]

在這種情況下,myAnswer為6

聽起來你想要bidict

>>> from bidict import bidict  # pip install bidict
>>> d = bidict({'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60})
>>> d['3'] 55
>>> d.inv[55] '3'

這允許在任一方向上進行O(1)查找。 現在,你可以遍歷someList和檢查元素是否是in d.inv有效。

第一部分,找到在列表中具有字典值的鍵的列表。

someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
someList = [51, 52, 53, 54, 55, 56]

res = [key for key, value in someDictionary.items() if value in someList]

第二部分,如果沒有從第一部分得到的結果,則找到具有最接近的較大值的鍵(續):

if not res:
    res = min ([(value, key) for key, value in someDictionary.items() if value > max(someList) ])[1]
myAnswer = ''
closest_to = someList[-1]
closest_diff = 0
for k in someDictionary:
    if someDictionary[k] in someList:
         myAnswer = k
         break; # stop the loop when exact match found
    diff = someDictionary[k] - closest_to
    if diff > 0 and diff < closest_diff:
         closest_diff = diff
         myAnswer = k # this would save key of larger but closest number to last in someList

首先使用列表lst收集所有值在lst鍵,如果沒有匹配項,則過濾值大於lst[-1] 根據鍵值和lst最后一項之差的abs值對它們進行排序后,取0索引,最接近的項。

dct = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
lst = [51, 52, 53, 54, 55, 56]

my_answer = [int(i) for i in dct if dct[i] in lst]
if my_answer:
    print(*my_answer) # => 3
else:
    close = [i for i in dct if int(dct[i]) > max(lst)]
    closest = sorted(close, key=lambda x: abs(dct.get(x) - lst[-1]))[0]
    print(closest) # => 6

如何在someDictionary中找到與someDictionary中的元素匹配的someList

字典用於將鍵映射到值。 在O(1)時間內不可能相反。 但是您可以在O( n )時間內進行迭代,直到可以將列表元素與字典值匹配為止。

為此,您可以使用簡單的for循環,迭代字典或列表。

d = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
L = [51, 52, 53, 54, 55, 56]

def find_key_dict(d, L):
    L_set = set(L)  # convert to set for O(1) lookup
    for k, v in d.items():
        if v in L_set:
            return k

def find_key_list(d, L):
    d_rev = {v: k for k, v in d.items()}  # reverse dict for value -> key map
    for i in L:
        if i in d_rev:
            return d_rev[i]

find_key_dict(d, L)  # '3'
find_key_list(d, L)  # '3'

也可以使用next將這些函數重寫為1行生成器表達式,但這不一定會更有效。

第二部分我需要做的是,如果someList不包含在一個元素someDictionary ,在發現價值someDictionary大於(但最接近)中最后一個元素someList

您可以使用for... else...構造帶有min的類似函數:

def find_key_dict(d, L):
    L_set = set(L)  # convert to set for O(1) lookup
    for k, v in d.items():
        if v in L_set:
            return k
    else:
        def min_func(x):
            diff = x[1] - L[-1]
            return diff <= 0, diff
        return min(d.items(), key=min_func)[0]

find_key_dict(d, L)  # '6'

對於第一個問題,您只是使用錯誤的運算符來檢查值是否在someList

for k, v in someDictionary.items():
    if v in someList:
        myAnswer = k

關於第二個問題,您可以通過這種方式擴展先前的代碼

for k, v in someDictionary.items():
     if v in someList:
         myAnswer = k
         break
else:
     myAnswer = None
     for k, v in someDictionary.items():
         if v > someList[-1] and (myAnswer is None or v < someDictionary[myAnswer]):
             myAnswer = k

如果您的字典和列表很大,尤其是如果您有很多列表要針對同一個字典進行測試,則值得准備數據以便更快地執行。

__init__最糟糕的操作是排序,即O(n * log(n))。 它使我們可以使用bisect在O(log(n))中最后一種情況下找到最接近的值。

from bisect import bisect


class FindInDict:
    def __init__(self, someDictionary):
        self.dict_by_values = {val: key for key, val in someDictionary.items()}
        self.dict_values_set = set(sorted_values)
        self.sorted_values = sorted(someDictionary.values())

    def find(self, someList):
        common = set(someList).intersection(self.dict_values_set)
        if common:
            key = self.dict_by_values[common.pop()]
        else:
            closest_value = self.sorted_values[bisect(self.sorted_values, someList[-1])]
            key = self.dict_by_values[closest_value]
        return key



someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}    
finder = FindInDict(someDictionary)

finder.find([51, 52, 53, 54, 55, 56])
# 3

finder.find([51, 52, 53, 54, 56])  # no common value
# 6

這可以解決您的問題的兩個部分,並且應該易於修改以處理可能彈出的任何討厭的“邊緣情況”:

someDictionary = {'1': 33, '2': 44, '3': 55, '4': 10, '5': 66, '6': 60}
someList = [51, 52, 53, 54, 55, 56]

myAnswer = [key for key in someDictionary if someDictionary[key] in someList]
if not myAnswer:
    diffs = {dict_key: dict_value-someList[-1]
                for dict_key, dict_value in someDictionary.items()
                    if dict_value-someList[-1] > 0}
    myAnswer = [min(diffs, key=diffs.get)]  # Key of value with minimum
                                            # (positive) difference
print(myAnswer)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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