Uzyskaj klucz według wartości w słowniku


632

Stworzyłem funkcję, która wyszukuje wieki za Dictionaryi pokazuje pasującą nazwę:

dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
for age in dictionary.values():
    if age == search_age:
        name = dictionary[age]
        print name

Wiem, jak porównać i znaleźć wiek, po prostu nie wiem, jak pokazać imię osoby. Ponadto dostaję błąd KeyErrorz wiersza 5. Wiem, że to nie jest poprawne, ale nie mogę wymyślić, jak sprawić, by wyszukiwał się wstecz.



Czy w słowniku znalazłbyś słowo oparte na jego definicji? NIE.
Jossie Calderon

Odpowiedzi:


563

Nie ma żadnego. dictnie jest przeznaczony do użycia w ten sposób.

dictionary = {'george': 16, 'amber': 19}
search_age = input("Provide age")
for name, age in dictionary.items():  # for name, age in dictionary.iteritems():  (for Python 2.x)
    if age == search_age:
        print(name)

137
W Python 3.x list.items()zamiast list.iteritems()powinny być stosowane
Jurij Petrovskiy

63
Nie zgadzam się ... Poniższa odpowiedź agfa jest bardziej konstruktywna. Zupełnie uzasadniony przypadek użycia nie jest „niezamierzony” (lista i tak pasuje do takiego przypadku użycia). dictMoże być dla wielu rzeczy w różnym czasie; Klucze i wartości mają oczywiście jasne znaczenie, ale dictprzedmioty o określonej wartości” są całkowicie uzasadnionym żądaniem. Zalecenie użycia listy par odrzuciłoby kontekst, że jeden element jest „ definicją ” z drugiego, np. Na listach parametrów ...
Louis Maddox,

1
Nie zgadzam się z tą odpowiedzią. Fakt, że jest to możliwość, jak pokazuje odpowiedź Stênio Elson, nie oznacza, że ​​nie była przeznaczona do takiego wykorzystania. W ogóle nie pomocny.
Tropicalrambler

Czy znajdziesz słowo w słowniku na podstawie jego definicji? NIE. @Tropicalrambler
Calderon

Chociaż masz rację, że standardowym zastosowaniem słownika słów jest wyszukiwanie definicji słowa za pomocą słowa = klucz i definicja = wartość, dzisiejsze języki programowania umożliwiają wyszukiwanie według wartości, jeśli to konieczne. Jeśli pracujesz z kluczem: obiekt parą wartości (nazwij go słownikiem, krotką, dowolną nazwą dla dowolnego języka). W Pythonie jest faktem, że nadal możesz indeksować wartości struktury, aby znaleźć odpowiednie klucze.
Tropicalrambler

599
mydict = {'george': 16, 'amber': 19}
print mydict.keys()[mydict.values().index(16)]  # Prints george

Lub w Python 3.x:

mydict = {'george': 16, 'amber': 19}
print(list(mydict.keys())[list(mydict.values()).index(16)])  # Prints george

Zasadniczo oddziela wartości słownika na liście, znajduje pozycję wartości, którą masz, i otrzymuje klucz w tej pozycji.

Więcej informacji keys()oraz .values()w Pythonie 3: Jak mogę uzyskać listę wartości z dict?


23
Wygląda świetnie, ale czy zawsze działa? Mam na myśli, czy list.keys()i list.values()funkcje generują elementy w tej samej kolejności?
iskorum

17
Tak, gwarantuje się ich spójność. Dodatkowo gwarantuje się, że kolejność nie będzie zmieniana przez iteracje, dopóki słownik nie zostanie zmodyfikowany.
Veedrac

9
To wydaje się być dobrym rozwiązaniem, ale indeks dał tylko jedną prawidłową wartość, więc jeśli masz wiele równych wartości, to powinno zwrócić wiele kluczy, prawda?
James Sapam,

12
@ArtOfWarfare docs.python.org/3/library/stdtypes.html#dict-views , „Jeśli widoki kluczy, wartości i elementów są iterowane bez żadnych zmian w słowniku, kolejność elementów będzie bezpośrednio odpowiadać”.
Veedrac,

5
@sinekonata: Nadal wykonuje kosztowną pętlę pod maską; pętla jest po prostu ukryta w indexmetodzie.
użytkownik2357112 obsługuje Monikę

252

Jeśli chcesz zarówno nazwę i wiek, powinieneś użyć tego, .items()co daje ci (key, value)krotki kluczowe :

for name, age in mydict.items():
    if age == search_age:
        print name

Możesz rozpakować krotkę w dwie osobne zmienne bezpośrednio w forpętli, a następnie dopasować wiek.

Powinieneś również rozważyć odwrócenie słownika, jeśli na ogół będziesz przeglądać według wieku, a żadna z dwóch osób nie ma tego samego wieku:

{16: 'george', 19: 'amber'}

dzięki czemu możesz wyszukać nazwę dla wieku, po prostu robiąc

mydict[search_age]

Nazwałem to mydictzamiastlist ponieważ listjest to nazwa typu wbudowanego i nie powinieneś używać tej nazwy do niczego innego.

Możesz nawet uzyskać listę wszystkich osób w danym wieku w jednym wierszu:

[name for name, age in mydict.items() if age == search_age]

lub jeśli w każdym wieku jest tylko jedna osoba:

next((name for name, age in mydict.items() if age == search_age), None)

co ci tylko da None jeśli nie ma nikogo w tym wieku.

Wreszcie, jeśli dictjest długi i używasz Pythona 2, powinieneś rozważyć użycie .iteritems()zamiast tego, .items()co zrobił Cat Plus Plus w swojej odpowiedzi, ponieważ nie trzeba tworzyć kopii listy.


9
Prawidłowo, ale jeśli zamierzasz przeprowadzić wyszukiwanie liniowe, równie dobrze możesz zastąpić je dictlistą par.
Fred Foo,

9
Chyba że twoje zwykłe działanie szuka wieku po imieniu, w takim przypadku ma dictto sens.
agf

2
Osobliwym wydaje się założenie, że w każdym wieku jest tylko jedna osoba, podczas gdy z drugiej strony logiczne jest, aby każda osoba miała jeden wiek.
Dannid

@Dannid Tak, ale problem można łatwo uogólnić. Na przykład możesz mieć tabelę przeglądową z unikalnymi kluczami i odpowiadającymi im unikatowymi wartościami. Następnie możesz sprawdzić rzeczy symetrycznie value --> keylubkey --> value
pfabri

67

Pomyślałem, że byłoby interesujące wskazać, które metody są najszybsze i w jakim scenariuszu:

Oto kilka testów, które przeprowadziłem (na MacBooku Pro 2012)

>>> def method1(list,search_age):
...     for name,age in list.iteritems():
...             if age == search_age:
...                     return name
... 
>>> def method2(list,search_age):
...     return [name for name,age in list.iteritems() if age == search_age]
... 
>>> def method3(list,search_age):
...     return list.keys()[list.values().index(search_age)]

Wyniki profile.run()dla każdej metody 100000 razy:

Metoda 1:

>>> profile.run("for i in range(0,100000): method1(list,16)")
     200004 function calls in 1.173 seconds

Metoda 2:

>>> profile.run("for i in range(0,100000): method2(list,16)")
     200004 function calls in 1.222 seconds

Metoda 3:

>>> profile.run("for i in range(0,100000): method3(list,16)")
     400004 function calls in 2.125 seconds

To pokazuje, że w przypadku małego nagrania metoda 1 jest najszybsza. Jest to najbardziej prawdopodobne, ponieważ zwraca pierwsze dopasowanie, w przeciwieństwie do wszystkich dopasowań, takich jak metoda 2 (patrz uwaga poniżej).


Co ciekawe, wykonując te same testy na dykcie, który mam z 2700 wpisami, otrzymuję zupełnie inne wyniki (tym razem uruchamiane 10000 razy):

Metoda 1:

>>> profile.run("for i in range(0,10000): method1(UIC_CRS,'7088380')")
     20004 function calls in 2.928 seconds

Metoda 2:

>>> profile.run("for i in range(0,10000): method2(UIC_CRS,'7088380')")
     20004 function calls in 3.872 seconds

Metoda 3:

>>> profile.run("for i in range(0,10000): method3(UIC_CRS,'7088380')")
     40004 function calls in 1.176 seconds

Więc tutaj metoda 3 jest znacznie szybsza. Po prostu pokazuje, że rozmiar twojego dykta wpłynie na wybraną metodę.

Uwagi: Metoda 2 zwraca listę wszystkich nazw, podczas gdy metody 1 i 3 zwracają tylko pierwsze dopasowanie. Nie rozważałem użycia pamięci. Nie jestem pewien, czy metoda 3 tworzy 2 dodatkowe listy (keys () i wartości ()) i przechowuje je w pamięci.


6
Tylko aktualizacja: wygląda na to, że dict.values ​​() i dict.keys () zwracają listy, które odwołują się do obiektów z oryginalnego dict, więc metoda 3 jest również tą, która wykorzystuje najmniej pamięci (tworzy tylko dwa cienkie obiekty listy które owijają treść dykt, podczas gdy inni tworzą elementy iteratora
Patrick

Chciałem po prostu sam to przetestować, przewinąć w dół, bam tam masz. Dzięki! Technicznie, jak już wskazałeś, metoda 2 nie robi dokładnie tego samego, co 1 i 3, ponieważ zwraca wszystkie dopasowania. miło byłoby zobaczyć wyniki np. powrotu następnego ([..]).
BluBb_mADe

Kolejną ważną uwagą do zrobienia jest wersja Python. Wiem, że niektóre wersje mają bardziej wydajne implementacje metod niż inne.
ArtOfWarfare

@Patrick: wszystkie metody używają bezpośrednich odniesień do wartości i kluczy, żadna nie ma żadnej przewagi pamięciowej. Z wyjątkiem widoków słownika Python 3 .keys()i` .values(), które są lekkie.
Martijn Pieters

53

wersja jednoliniowa: (i to stary słownik, p to słownik odwrócony)

objaśnienie: i.keys()i i.values()zwraca dwie listy odpowiednio z kluczami i wartościami słownika. Funkcja zip ma możliwość wiązania list w celu utworzenia słownika.

p = dict(zip(i.values(),i.keys()))

Ostrzeżenie: Działa to tylko wtedy, gdy wartości są haszowalne i unikalne.



17
... a gdy nie ma zduplikowanych wartości.
ely

3
Piękny. Napisz powyższy komentarz, oczywiście działa to tylko wtedy, gdy nie ma zduplikowanych wartości, ale pytanie, które zapoczątkowało ten wątek, zakłada, że ​​mamy funkcję jeden do jednego, więc biorąc pod uwagę to założenie, jest to najbardziej eleganckie odpowiedź zdecydowanie.
John Strong

1
rozwijanie wartości skrótu: jeśli twoje wartości są listami / zestawami, przekonwertuj je na krotki, aby to zadziałało (nadal muszą być unikalne).
mion

28
a = {'a':1,'b':2,'c':3}
{v:k for k, v in a.items()}[1]

albo lepiej

{k:v for k, v in a.items() if v == 1}

5
Co się stanie, jeśli istnieje inny klucz, który ma tę samą wartość? Może być sposobem pytonicznym. Ale nie jest to dobry pomysł.
7H3 IN5ID3R,

Dobra uwaga, dodałem rozwiązanie, które działa z nietypowymi wartościami
Jelen

25
key = next((k for k in my_dict if my_dict[k] == val), None)

Czy mogę mieć również „inne” w tej samej linii? Na przykład, gdy mojej wartości nie ma w wartościach
dyktowanych

lKey = [k for k, v in lDictionary.iteritems() if v == lValue][0] or 'else-key'
faham


13

Uważam, że ta odpowiedź jest dla mnie bardzo skuteczna, ale nie bardzo łatwa do odczytania.

Aby było bardziej jasne, możesz odwrócić klucz i wartość słownika. To sprawia, że ​​klucze wartości i klucze wartości, jak pokazano tutaj .

mydict = {'george':16,'amber':19}
res = dict((v,k) for k,v in mydict.iteritems())
print(res[16]) # Prints george

lub

mydict = {'george':16,'amber':19}
dict((v,k) for k,v in mydict.iteritems())[16]

który jest zasadniczo taki sam jak ten inny odpowiedź .


12

Jeśli chcesz znaleźć klucz według wartości, możesz użyć słownika do utworzenia słownika odnośników, a następnie użyć go do znalezienia klucza z wartości.

lookup = {value: key for key, value in self.data}
lookup[value]

11

Można uzyskać za pomocą przycisku dict.keys(), dict.values()a list.index()metody, patrz przykłady kodu poniżej:

names_dict = {'george':16,'amber':19}
search_age = int(raw_input("Provide age"))
key = names_dict.keys()[names_dict.values().index(search_age)]

2
nie używać zdefiniowanej search_agevar na następnej linii ... Może należy wymienić valuez search_age?
Andersson,

2
Pojawia się ten błąd: obiekt „dict_values” nie ma atrybutu „index”
Blue_Elephant

@Blue_Elephant, czy możesz podać fragment kodu, który zawiera błąd i wersję w języku Python ( type(dict_values)przydatny byłby również wydruk )?
Andriy Ivaneyko,

9

Oto moje podejście do tego problemu. :) Właśnie zacząłem uczyć się języka Python, więc nazywam to:

Rozwiązanie „Zrozumiały dla początkujących”.

#Code without comments.

list1 = {'george':16,'amber':19, 'Garry':19}
search_age = raw_input("Provide age: ")
print
search_age = int(search_age)

listByAge = {}

for name, age in list1.items():
    if age == search_age:
        age = str(age)
        results = name + " " +age
        print results

        age2 = int(age)
        listByAge[name] = listByAge.get(name,0)+age2

print
print listByAge

.

#Code with comments.
#I've added another name with the same age to the list.
list1 = {'george':16,'amber':19, 'Garry':19}
#Original code.
search_age = raw_input("Provide age: ")
print
#Because raw_input gives a string, we need to convert it to int,
#so we can search the dictionary list with it.
search_age = int(search_age)

#Here we define another empty dictionary, to store the results in a more 
#permanent way.
listByAge = {}

#We use double variable iteration, so we get both the name and age 
#on each run of the loop.
for name, age in list1.items():
    #Here we check if the User Defined age = the age parameter 
    #for this run of the loop.
    if age == search_age:
        #Here we convert Age back to string, because we will concatenate it 
        #with the person's name. 
        age = str(age)
        #Here we concatenate.
        results = name + " " +age
        #If you want just the names and ages displayed you can delete
        #the code after "print results". If you want them stored, don't...
        print results

        #Here we create a second variable that uses the value of
        #the age for the current person in the list.
        #For example if "Anna" is "10", age2 = 10,
        #integer value which we can use in addition.
        age2 = int(age)
        #Here we use the method that checks or creates values in dictionaries.
        #We create a new entry for each name that matches the User Defined Age
        #with default value of 0, and then we add the value from age2.
        listByAge[name] = listByAge.get(name,0)+age2

#Here we print the new dictionary with the users with User Defined Age.
print
print listByAge

.

#Results
Running: *\test.py (Thu Jun 06 05:10:02 2013)

Provide age: 19

amber 19
Garry 19

{'amber': 19, 'Garry': 19}

Execution Successful!

9
get_key = lambda v, d: next(k for k in d if d[k] is v)

Miły jednowarstwowy. Jednakże, isnależy stosować wyłącznie do testowania równości singletons ( None, True, Falseitp). Fakt, że CPython ponownie używa literałów łańcuchowych (i dlatego a = 'foobar'; a is 'foobar'jest True), jest szczegółem implementacyjnym i nie należy na nim polegać.
piit79,

1
I jeszcze jeden komentarz: get_keywyrzuci, StopIterationjeśli wartość nie istnieje w słowniku - lepiej byłoby użyć tej, next(..., None)która zwróciłaby się, Nonegdyby wartość nie została znaleziona.
piit79

Niewielka modyfikacja zadziała, jeśli słownik nie zawiera pojedynczych elementów, ale ustawia:get_first_key = lambda v, d: next((k for k in d if (v in d[k] is not None)), None)
supernowa

7

Zastanów się nad użyciem Pand. Jak stwierdzono w „Pythonie do analizy danych” Williama McKinneya

Innym sposobem myślenia o serii jest uporządkowany dykt o stałej długości, ponieważ jest on mapowaniem wartości indeksu na wartości danych. Może być używany w wielu kontekstach, w których możesz użyć dyktowania.

import pandas as pd
list = {'george':16,'amber':19}
lookup_list = pd.Series(list)

Aby wysłać zapytanie do serii, wykonaj następujące czynności:

lookup_list[lookup_list.values == 19]

Co daje:

Out[1]: 
amber    19
dtype: int64

Jeśli potrzebujesz zrobić coś innego z danymi wyjściowymi, przydatne może być przekształcenie odpowiedzi w listę:

answer = lookup_list[lookup_list.values == 19].index
answer = pd.Index.tolist(answer)

Jest twórcą pand. Jednak bardziej znany jest jako Wes.
Axel

6

Tutaj odzyskuje klucz i słownik do znalezienia w słowniku. Następnie zapętlamy klucze w słowniku i porównujemy je z wartością i zwracamy ten konkretny klucz.

def recover_key(dicty,value):
    for a_key in dicty.keys():
        if (dicty[a_key] == value):
            return a_key

4
for name in mydict:
    if mydict[name] == search_age:
        print(name) 
        #or do something else with it. 
        #if in a function append to a temporary list, 
        #then after the loop return the list

1
Korzystanie z pętli for i append jest znacznie wolniejsze niż czytanie listy, a także dłuższe.
alexpinho98

4

możemy uzyskać Keyod dictprzez:

def getKey(dct,value):
     return [key for key in dct if (dct[key] == value)]

3

odpowiedziano, ale można to zrobić za pomocą fantazyjnego użycia „mapy / zmniejszenia”, np .:

def find_key(value, dictionary):
    return reduce(lambda x, y: x if x is not None else y,
                  map(lambda x: x[0] if x[1] == value else None, 
                      dictionary.iteritems()))

3

Cat Plus Plus wspomniał, że nie tak ma być używany słownik. Dlatego:

Definicja słownika jest analogiczna do definicji mapowania w matematyce. W tym przypadku dykt jest mapowaniem K (zestawu kluczy) na V (wartości) - ale nie odwrotnie. Jeśli wyrejestrujesz dyktando, spodziewasz się zwrócić dokładnie jedną wartość. Jednak mapowanie różnych kluczy na tę samą wartość jest całkowicie legalne, np .:

d = { k1 : v1, k2 : v2, k3 : v1}

Kiedy wyszukujesz klucz według odpowiadającej mu wartości, zasadniczo odwracasz słownik. Ale mapowanie niekoniecznie musi być odwracalne! W tym przykładzie zapytanie o klucz odpowiadający v1 może dać k1 lub k3. Powinieneś zwrócić oba? Tylko pierwszy znaleziony? Dlatego indexof () jest niezdefiniowany dla słowników.

Jeśli znasz swoje dane, możesz to zrobić. Ale interfejs API nie może zakładać, że dowolny słownik jest odwracalny, stąd brak takiej operacji.


3

oto moje zdanie na ten temat. Jest to dobre do wyświetlania wielu wyników na wypadek, gdybyś ich potrzebował. Więc dodałem również listę

myList = {'george':16,'amber':19, 'rachel':19, 
           'david':15 }                         #Setting the dictionary
result=[]                                       #Making ready of the result list
search_age = int(input('Enter age '))

for keywords in myList.keys():
    if myList[keywords] ==search_age:
    result.append(keywords)                    #This part, we are making list of results

for res in result:                             #We are now printing the results
    print(res)

I to wszystko...


3
d= {'george':16,'amber':19}

dict((v,k) for k,v in d.items()).get(16)

Dane wyjściowe są następujące:

-> prints george

[k dla k, v in d.items () if v == 16]
auro

3

Nie ma łatwego sposobu na znalezienie klucza na liście poprzez „sprawdzenie” wartości. Jeśli jednak znasz wartość, iterując po kluczach, możesz wyszukać wartości w słowniku według elementu. Jeśli D [element], gdzie D jest obiektem słownikowym, jest równe kluczowi, który próbujesz wyszukać, możesz wykonać kod.

D = {'Ali': 20, 'Marina': 12, 'George':16}
age = int(input('enter age:\t'))  
for element in D.keys():
    if D[element] == age:
        print(element)

3

Musisz użyć słownika i odwrócić ten słownik. Oznacza to, że potrzebujesz innej struktury danych. Jeśli używasz Pythona 3, użyj enummodułu, ale jeśli używasz Pythona 2.7, użyj go z enum34powrotem przeniesionego do Pythona 2.

Przykład:

from enum import Enum

class Color(Enum): 
    red = 1 
    green = 2 
    blue = 3

>>> print(Color.red) 
Color.red

>>> print(repr(Color.red)) 
<color.red: 1=""> 

>>> type(Color.red) 
<enum 'color'=""> 
>>> isinstance(Color.green, Color) 
True 

>>> member = Color.red 
>>> member.name 
'red' 
>>> member.value 
1 


2

Tylko moja odpowiedź w lambdai filter.

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )

1

już odpowiedziano, ale ponieważ kilka osób wspomniało o odwróceniu słownika, oto jak to zrobić w jednym wierszu (zakładając odwzorowanie 1: 1) i kilka różnych danych perf:

python 2.6:

reversedict = dict([(value, key) for key, value in mydict.iteritems()])

2.7+:

reversedict = {value:key for key, value in mydict.iteritems()}

jeśli uważasz, że nie jest to 1: 1, nadal możesz utworzyć rozsądne odwrotne mapowanie za pomocą kilku linii:

reversedict = defaultdict(list)
[reversedict[value].append(key) for key, value in mydict.iteritems()]

jak powolne jest to: wolniejsze niż proste wyszukiwanie, ale nie tak wolno, jak mogłoby się wydawać - w „prostym” słowniku 100000, „szybkim” wyszukiwaniu (tj. szukaniu wartości, która powinna znajdować się na początku klawiszy) było około 10 razy szybsze niż odwrócenie całego słownika, a „powolne” wyszukiwanie (pod koniec) około 4–5 razy szybciej. Po co najmniej 10 przeglądach jest to opłacone.

druga wersja (z listami na element) zajmuje około 2,5 razy tyle, co wersja prosta.

largedict = dict((x,x) for x in range(100000))

# Should be slow, has to search 90000 entries before it finds it
In [26]: %timeit largedict.keys()[largedict.values().index(90000)]
100 loops, best of 3: 4.81 ms per loop

# Should be fast, has to only search 9 entries to find it. 
In [27]: %timeit largedict.keys()[largedict.values().index(9)]
100 loops, best of 3: 2.94 ms per loop

# How about using iterkeys() instead of keys()?
# These are faster, because you don't have to create the entire keys array.
# You DO have to create the entire values array - more on that later.

In [31]: %timeit islice(largedict.iterkeys(), largedict.values().index(90000))
100 loops, best of 3: 3.38 ms per loop

In [32]: %timeit islice(largedict.iterkeys(), largedict.values().index(9))
1000 loops, best of 3: 1.48 ms per loop

In [24]: %timeit reversedict = dict([(value, key) for key, value in largedict.iteritems()])
10 loops, best of 3: 22.9 ms per loop

In [23]: %%timeit
....: reversedict = defaultdict(list)
....: [reversedict[value].append(key) for key, value in largedict.iteritems()]
....:
10 loops, best of 3: 53.6 ms per loop

Miałem także kilka interesujących wyników z ifilter. Teoretycznie ifilter powinien być szybszy, ponieważ możemy używać itervalues ​​() i być może nie musimy tworzyć / przechodzić przez całą listę wartości. W praktyce wyniki były ... dziwne ...

In [72]: %%timeit
....: myf = ifilter(lambda x: x[1] == 90000, largedict.iteritems())
....: myf.next()[0]
....:
100 loops, best of 3: 15.1 ms per loop

In [73]: %%timeit
....: myf = ifilter(lambda x: x[1] == 9, largedict.iteritems())
....: myf.next()[0]
....:
100000 loops, best of 3: 2.36 us per loop

Tak więc, w przypadku małych odsunięć, był on znacznie szybszy niż jakakolwiek poprzednia wersja (2,36 * u * S w porównaniu z minimum 1,48 * m * S w poprzednich przypadkach). Jednak w przypadku dużych przesunięć pod koniec listy było to znacznie wolniejsze (15,1 ms w porównaniu z tym samym 1,48 ms). Małe oszczędności na niskim poziomie nie są warte kosztu na wysokim poziomie, imho.


Tak bardzo chcę, aby to (reverseict = defaultdict (lista) reverseict [wartość] .append (klucz) dla klucza, wartość w largedict.iteritems ()]) działało, ale używając Pythona 2.7.3, pojawia się błąd składniowy tego słowa „for”
slashdottir

czy to właśnie wpisałeś? jeśli [w niej brakuje . w przeciwnym razie upewnij się, że jest na dwóch liniach, lub wstaw ;między nimi, jeśli nie jest.
Corley Brigman

1

Czasami może być potrzebna int ():

titleDic = {'Фильмы':1, 'Музыка':2}

def categoryTitleForNumber(self, num):
    search_title = ''
    for title, titleNum in self.titleDic.items():
        if int(titleNum) == int(num):
            search_title = title
    return search_title

1

Oto rozwiązanie, które działa zarówno w Python 2, jak i Python 3:

dict((v, k) for k, v in list.items())[search_age]

Część do [search_age]zbudowania odwrotnego słownika (gdzie wartości są kluczami i odwrotnie). Możesz stworzyć metodę pomocniczą, która buforuje ten odwrócony słownik w następujący sposób:

def find_name(age, _rev_lookup=dict((v, k) for k, v in ages_by_name.items())):
    return _rev_lookup[age]

lub nawet bardziej ogólnie fabrykę, która stworzyłaby metodę wyszukiwania nazw według wieku dla jednej lub większej liczby list

def create_name_finder(ages_by_name):
    names_by_age = dict((v, k) for k, v in ages_by_name.items())
    def find_name(age):
      return names_by_age[age]

więc będziesz mógł zrobić:

find_teen_by_age = create_name_finder({'george':16,'amber':19})
...
find_teen_by_age(search_age)

Zauważ, że ja przemianowany listna ages_by_nameod dawna jest predefiniowany typ.


1

W ten sposób uzyskujesz dostęp do słownika, aby robić to, co chcesz:

list = {'george': 16, 'amber': 19}
search_age = raw_input("Provide age")
for age in list:
    if list[age] == search_age:
        print age

oczywiście, wasze imiona są tak nieczułe, że wygląda na to, że drukuje epokę, ale to NIE drukuje imienia. Ponieważ korzystasz z nazwy, staje się bardziej zrozumiałe, jeśli napiszesz:

list = {'george': 16, 'amber': 19}
search_age = raw_input("Provide age")
for name in list:
    if list[name] == search_age:
        print name

Jeszcze lepiej:

people = {'george': {'age': 16}, 'amber': {'age': 19}}
search_age = raw_input("Provide age")
for name in people:
    if people[name]['age'] == search_age:
        print name

1
dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
key = [filter( lambda x: dictionary[x] == k  , dictionary ),[None]][0] 
# key = None from [None] which is a safeguard for not found.

W przypadku wielu wystąpień użyj:

keys = [filter( lambda x: dictionary[x] == k  , dictionary )]

*** NameError: global name 'dictionary' is not defined
Bishwas Mishra

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )
Bishwas Mishra
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.