sözlükte bir listeden bir öğe bulun ve o anahtarı dönmek

oy
1

Ben olsaydı someDictionaryolarak tanımlanan

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

ve someListgibi tanımlanmıştır

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

nasıl anahtar bulabilirim someDictionaryki unsurunu eşleşir someList? Şimdilik, birden fazla eşleşme olmayacak varsayıyorum.

Ben böyle bir şey olacağını düşünürdüm:

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

Yukarıdaki kod göz önüne alındığında, myAnswerolurdu3

Yapmam gereken ikinci bölümü somelist bulunan bir öğe içermiyorsa, olduğunu someDictionary, değeri bulmak someDictionarydaha büyük somelist son öğe (ama en yakın)someList[-1]

Bu durumda, myAnswer olurdu 6

Oluştur 20/10/2018 saat 14:12
kaynak kullanıcı
Diğer dillerde...                            


8 cevaplar

oy
3

Bir istediğiniz gibi geliyor 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'

Bu sayede O (1) her iki yönde aramaları. Şimdi, döngü üzerinde can someListve bir eleman olup olmadığını kontrol in d.invverimli.

Cevap 20/10/2018 saat 14:38
kaynak kullanıcı

oy
2

İlk kısım, listedeki bir sözlük değere sahip tuşlarının listesini bulun.

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]

İkinci bölüm, birinci bölümü hiçbir sonuç ise, (devamı) en yakın daha büyük bir değere sahip anahtar bulmak:

if not res:
    res = min ([(value, key) for key, value in someDictionary.items() if value > max(someList) ])[1]
Cevap 20/10/2018 saat 14:20
kaynak kullanıcı

oy
1

İşte sorunuzun her iki bölümünü kolları ve açılır olabilecek sinir bozucu "kenar-durumlarda" işlemek için değiştirmek kolay olması gereken bir şey:

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)
Cevap 20/10/2018 saat 16:00
kaynak kullanıcı

oy
1

senin sözlük ve liste büyükse, aynı sözlüğe karşı test etmek için birçok listeleri var ve özellikle o daha hızlı yürütülmesine sahip olmak için verilerinizi hazırlarken değer olabilir.

En kötü çalışma __init__O'dur sıralama olduğu, (n x log (n)). Bu bize kullanmanıza olanak verir bisectO da son durumda en yakın değeri (log (n)) bulmak için.

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
Cevap 20/10/2018 saat 15:08
kaynak kullanıcı

oy
1

İlk soru için, sadece değer olup olmadığını kontrol etmek için yanlış operatörü kullanıyorsunuz someList

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

ikinci soruya Hakkında bu şekilde önceki kod uzatabilir

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
Cevap 20/10/2018 saat 14:33
kaynak kullanıcı

oy
1

Nasıl anahtar bulabilirim someDictionaryki unsurunu eşleşir someList?

Bir sözlük değerlerine haritası anahtarlarını kullanılır. Ters O (1) zaman mümkün değildir. Ama O (içinde yineleme yapabilirsiniz n Eğer bir sözlük değere sahip bir liste elemanı eşleşebilir kadar) zamanında.

Basit kullanabilirsiniz for, bunun için döngü sizin sözlüğünü veya liste yineleme ya.

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'

Bu 1-satır jeneratör ifadeler olarak bu işlevleri yeniden yazmak da mümkündür next, ama bu mutlaka daha verimli olmayacaktır.

Ben eğer, yapmanız gereken ikinci bölümü someListise bir öğe içermiyor someDictionary, değeri bulmak someDictionary daha büyük (ama en yakın) son öğe içindesomeList

Bir kullanan benzer bir işlev yazabilirsiniz for... else...ile yapısı 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'
Cevap 20/10/2018 saat 14:27
kaynak kullanıcı

oy
1

İlk kullanım liste anlama, değerleri olan tüm anahtarları toplamak için lsteşleşme sonra, değeri daha büyüktür anahtarları için filtre varsa, lst[-1]. Sonra sıralama onları anahtarlar değerlerin farklılık ve son öğenin abs değerine dayalı lstve almak 0endeksi, en yakın öğeyi.

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
Cevap 20/10/2018 saat 14:25
kaynak kullanıcı

oy
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
Cevap 20/10/2018 saat 14:24
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more