Schlüssel für den Wert im Wörterbuch

Ich habe eine Funktion gemacht, die im Wörterbuch nachsehen und den passenden Namen zeigen wird:

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

Ich weiß, wie man vergleiche und finde das Alter Ich weiß einfach nicht, wie man den Namen der Person zu zeigen. Darüber hinaus KeyError ich ein KeyError wegen der Zeile 5. Ich weiß, es ist nicht richtig, aber ich kann nicht herausfinden, um es rückwärts zu suchen.

  • Python: Effiziente Möglichkeit, zu überprüfen, ob das Wörterbuch leer ist oder nicht
  • Wie man ein Wörterbuch aus einer Textdatei mit Python macht
  • Wie füge ich Wörterbücher zusammen in Python zusammen?
  • Python erstellen Variablen aus Wörterbucheinträgen
  • Wie man dict mit childrens aus dict mit parent_id erstellt
  • BestelltDict vs Dict in Python
  • Summe entsprechende Elemente von mehreren Python-Wörterbüchern
  • Wie man testet, wenn ein Wörterbuch bestimmte Schlüssel enthält
  • 26 Solutions collect form web for “Schlüssel für den Wert im Wörterbuch”

    Da ist gar nichts. dict ist nicht beabsichtigt, auf diese Weise verwendet zu werden.

     for name, age in list.iteritems(): if age == search_age: print name 
     mydict = {'george':16,'amber':19} print mydict.keys()[mydict.values().index(16)] # Prints george 

    Oder in Python 3.x:

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

    Grundsätzlich trennt es die Werte des Wörterbuchs in einer Liste, findet die Position des Wertes, den Sie haben, und bekommt den Schlüssel an dieser Position.

    Mehr über keys() und .values() in Python 3: Python: einfachste Weg, um Liste von Werten aus dict zu erhalten?

    Wenn du sowohl den Namen als auch das Alter .items() , solltest du die .items() die dir Schlüssel- (key, value) Tupel gibt:

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

    Sie können das Tupel in zwei getrennte Variablen in der for Schleife auspacken und dann dem Alter entsprechen.

    Sie sollten auch überlegen, das Wörterbuch umzukehren, wenn Sie in der Regel nach oben suchen nach Alter, und keine zwei Menschen haben das gleiche Alter:

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

    So können Sie den Namen für ein Alter, indem Sie nur tun

     mydict[search_age] 

    Ich habe es angerufen, mydict statt der list weil list ist der Name eines eingebauten Typs, und Sie sollten nicht diesen Namen für etwas anderes verwenden.

    Sie können sogar eine Liste aller Menschen mit einem bestimmten Alter in einer Zeile:

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

    Oder wenn es nur eine Person mit jedem Alter gibt:

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

    Das gibt dir einfach None wenn es niemanden mit diesem Alter gibt.

    Schließlich, wenn das dict ist lang und du bist auf Python 2, sollten Sie die Verwendung von .iteritems() anstelle von .items() als Cat Plus Plus in seiner Antwort, da es nicht brauchen, um eine Kopie der Liste.

    Ich dachte, es wäre interessant, darauf hinzuweisen, welche Methoden am schnellsten sind und in welchem ​​Szenario:

    Hier sind einige Tests, die ich lief (auf einem 2012 MacBook Pro)

     >>> 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)] 

    Ergebnisse von profile.run() bei jeder Methode 100000 mal:

    Methode 1:

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

    Methode 2:

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

    Methode 3:

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

    So zeigt das, dass für ein kleines Dikt Methode 1 am schnellsten ist. Dies ist höchstwahrscheinlich, weil es das erste Spiel zurückgibt, im Gegensatz zu allen Spielen wie Methode 2 (siehe Hinweis unten).


    Interessanterweise, die gleichen Tests auf einem dict ich habe mit 2700 Einträgen, bekomme ich ganz andere Ergebnisse (diesmal 10000 mal laufen):

    Methode 1:

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

    Methode 2:

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

    Methode 3:

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

    Also hier ist Methode 3 viel schneller. Gibt es einfach, die Größe deines Diktats zu zeigen, welche Methode du auswählst.

    Anmerkungen: Methode 2 gibt eine Liste aller Namen zurück, während die Methoden 1 und 3 nur die erste Übereinstimmung zurückgeben. Ich habe den Speicherverbrauch nicht berücksichtigt. Ich bin mir nicht sicher, ob Methode 3 2 zusätzliche Listen (Schlüssel () und Werte ()) erstellt und sie im Speicher speichert.

    Eine Zeile Version: (Ich bin ein altes Wörterbuch, p ist ein umgekehrtes Wörterbuch)

     p = dict(zip(i.values(),i.keys())) 
     lKey = [key for key, value in lDictionary.iteritems() if value == lValue][0] 
     a = {'a':1,'b':2,'c':3} {v:k for k, v in a.items()}[1] 

    oder besser

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

    Hier ist meine Aufnahme auf dieses Problem. 🙂 Ich habe gerade erst begonnen, Python zu lernen, also nenne ich das:

    "Die Verständlichkeit für Anfänger" -Lösung.

     #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! 

    Sie können Schlüssel unter Verwendung von dict.keys() , dict.values() und list.index() Methoden erhalten, siehe Codebeispiele unten:

     names_dict = {'george':16,'amber':19} search_age = int(raw_input("Provide age")) key = names_dict.keys()[names_dict.values().index(search_age)] 
     for name in mydict.keys(): 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 

    Wenn du den Schlüssel durch den Wert finden möchtest, kannst du ein Wörterbuchverstehen verwenden, um ein Suchwörterbuch zu erstellen und dann den Schlüssel aus dem Wert zu finden.

     lookup = {value: key for key, value in self.data} lookup[value] 
     def get_Value(dic,value): for name in dic: if dic[name] == value: del dic[name] return name 

    Es ist geantwortet, aber es könnte mit einer Phantasie "Karte / reduzieren" Gebrauch gemacht werden, zB:

     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())) 

    Es gibt keinen einfachen Weg, um einen Schlüssel in einer Liste zu finden, indem Sie den Wert nachschlagen. Allerdings, wenn Sie den Wert kennen, iterating durch die Schlüssel, können Sie nachschlagen, Werte in das Wörterbuch durch das Element. Wenn D [Element], wo D ist ein Wörterbuch-Objekt, ist gleich der Taste, die Sie versuchen, nachschlagen, können Sie einige Code ausführen.

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

    Cat Plus Plus erwähnt, dass dies nicht ist, wie ein Wörterbuch verwendet werden soll. Hier ist der Grund:

    Die Definition eines Wörterbuches ist analog zu einer Mapping in Mathematik. In diesem Fall ist ein Dikt eine Abbildung von K (der Satz von Schlüsseln) auf V (die Werte) – aber nicht umgekehrt. Wenn Sie einen Dict entwerfen, erwarten Sie genau einen Wert zurückzugeben. Aber es ist völlig legal für verschiedene Schlüssel auf den gleichen Wert zuzuordnen, zB:

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

    Wenn du einen Schlüssel durch den entsprechenden Wert schaust, wirst du das Wörterbuch im Wesentlichen invertieren. Aber eine Kartierung ist nicht unbedingt invertierbar! In diesem Beispiel könnte die Frage nach dem Schlüssel, der v1 entspricht, k1 oder k3 ergeben. Sollten Sie beide zurückkehren? Nur der erste gefunden Deshalb ist indexof () für Wörterbücher undefiniert.

    Wenn Sie Ihre Daten kennen, können Sie dies tun. Aber eine API kann nicht davon ausgehen, dass ein beliebiges Wörterbuch invertierbar ist, also das Fehlen einer solchen Operation.

    Hier ist meine nehmen auf sie. Dies ist gut für die Anzeige mehrerer Ergebnisse nur für den Fall, dass Sie eine benötigen. Also habe ich auch die Liste hinzugefügt

     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) 

    Und das ist es…

    Manchmal kann int () benötigt werden:

     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 

    Du musst ein Wörterbuch verwenden und dieses Wörterbuch umkehren. Es bedeutet, dass Sie eine andere Datenstruktur benötigen. Wenn Sie in Python 3 sind, verwenden Sie enum Modul, aber wenn Sie mit python 2.7 verwenden enum34 die wieder für python 2 portiert ist.

    Beispiel:

     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 
     def recover_key(dictionary,value): for a_key in dicty.keys(): if (dicty[a_key] == value): return a_key 

    Wurde bereits beantwortet, aber da mehrere Leute erwähnt Umkehrung des Wörterbuchs, hier ist, wie Sie es in einer Zeile (vorausgesetzt 1: 1 Mapping) und einige verschiedene perf Daten:

    Python 2.6:

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

    2.7+:

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

    Wenn du denkst, es ist nicht 1: 1, kannst du immer noch eine vernünftige Reverse Mapping mit ein paar Zeilen erstellen:

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

    Wie langsam ist das: langsamer als eine einfache suche, aber nicht annähernd so langsam wie du denkst – auf einem 'geraden' 100000 eintragungswörterbuch, eine 'schnelle' suche (dh nach einem wert, der früh in den schlüsseln sein sollte) War etwa 10x schneller als das gesamte Wörterbuch umzukehren, und eine "langsame" Suche (gegen Ende) etwa 4-5x schneller. Also nach höchstens etwa 10 Lookups, ist es für sich bezahlt.

    Die zweite Version (mit Listen pro Artikel) dauert ca. 2,5x, solange die einfache Version.

     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 

    Hatte auch einige interessante Ergebnisse mit ifilter. Theoretisch sollte ifilter schneller sein, da wir itervalues ​​() nutzen können und eventuell nicht die gesamte Werteliste erstellen / durchlaufen müssen. In der Praxis waren die Ergebnisse … ungerade …

     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 

    Also, für kleine Offsets war es dramatisch schneller als jede vorherige Version (2.36 * u * S gegen ein Minimum von 1,48 * m * S für vorherige Fälle). Allerdings war für große Offsets in der Nähe des Endes der Liste, war es dramatisch langsamer (15,1 ms gegenüber dem gleichen 1,48 ms). Die kleinen Einsparungen am unteren Ende ist nicht wert die Kosten am High-End, Imho.

    Dies ist, wie Sie das Wörterbuch zu tun, was Sie wollen:

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

    Natürlich sind deine Namen so aus, dass es aussieht, als würde es ein Alter drucken, aber es drückt den Namen aus. Da du namentlich nimmst, wird es verständlicher, wenn du schreibst:

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

    Noch besser:

     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 
     d= {'george':16,'amber':19} dict((v,k) for k,v in d.items()).get(16) 

    Die Ausgabe ist wie folgt:

     -> prints george 

    Hier ist eine Lösung, die sowohl in Python 2 als auch in Python 3 funktioniert:

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

    Der Teil bis [search_age] konstruiert das reverse Wörterbuch (wobei Werte Schlüssel sind und umgekehrt). Sie könnten eine Helper-Methode erstellen, die dieses umgekehrte Wörterbuch wie folgt zwischenspeichern wird:

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

    Oder sogar allgemeiner eine Fabrik, die eine Nachnamen-Lookup-Methode für eine oder mehrere von Ihnen Listen erstellen würde

     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] 

    Also könntest du tun:

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

    Beachten Sie, dass ich die list in ages_by_name umbenannt ages_by_name da der vorherige ein vordefinierter Typ ist.

    Ich weiß, das ist alt, aber man konnte ganz einfach alle Menschen in der Liste mit Ihrem Suchalter mit Listenverständnis finden.

     ages = {'george':16,'amber':19} search = 16 print([name for (name, age) in ages.items() if age == search]) 

    Ich hoffe das könnte helfen …

     for key in list: if list[key] == search_value: return key 

    Ein einfacher Weg dazu könnte sein:

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

    Dies gibt eine Liste der Schlüssel mit dem Wert zurück, der mit search_age übereinstimmt. Sie können auch "list == search_age" mit jeder anderen Konditionsanweisung ersetzen, wenn nötig.

    Python ist die beste Programmiersprache der Welt.