2012-04-04 10 views
1

Mögliche Duplizieren:
Inverse dictionary lookup - PythonIndex Python Wörterbuch von Wert

Gibt es eine eingebaute Möglichkeit, ein Wörterbuch von Wert in Python zu indizieren.

z.B. so etwas wie:

dict = {'fruit':'apple','colour':'blue','meat':'beef'} 
print key where dict[key] == 'apple' 

oder:

dict = {'fruit':['apple', 'banana'], 'colour':'blue'} 
print key where 'apple' in dict[key] 

oder habe ich es manuell Schleife?

+2

Seien Sie gewarnt, dass es keine Einschränkung gibt, dass die 'Werte' im' dict' eindeutig sind, nur die 'Schlüssel'. Was passiert, wenn Sie in Ihrem Diktat zwei identische Schlüssel haben? – Hooked

+2

@Hooked Meinst du "zwei identische Werte"? –

+0

@ root45 ja ich meine identische "Werte" nicht "Schlüssel", tut mir leid. Etwas wie: 'A = {1: 'foo', 2: 'foo'}'. Was ist das Gegenteil von 'foo', das hier zurückkommen soll? – Hooked

Antwort

4

Sie müssen es manuell Schleife, aber wenn Sie die Nachschlag benötigen wiederholt dies ist ein handliches Trick:

d1 = {'fruit':'apple','colour':'blue','meat':'beef'} 

d1_rev = dict((v, k) for k, v in d1.items()) 

Anschließend können Sie das Reverse-Wörterbuch wie folgt verwenden:

>>> d1_rev['blue'] 
'colour' 
>>> d1_rev['beef'] 
'meat' 
+0

Sie sollten mindestens erwähnen, was die letzte Zeile tut? –

+0

meh. sieht ziemlich offensichtlich – bernie

+2

@bernie: Es ist nicht offensichtlich, OP, sonst würde er nicht fragen. Ein einfaches "builds reverse dictionary (value-> key)" wäre genug, aber ohne etwas, das ist ein wenig verwirrend –

5

könnten Sie ein list comprehension verwenden:

my_dict = {'fruit':'apple','colour':'blue','meat':'beef'} 
print [key for key, value in my_dict.items() if value == 'apple'] 

Der obige Code ist fast genau das, wh an dem Sie wollen:

Drucktaste, dict [key] == ‚Apfel‘

Die Liste Verständnis wird von Ihrem Wörterbuch der durch alle Schlüssel, Wert-Paare gegeben gehen items method, und machen ein neue Liste aller Schlüssel mit dem Wert 'apple'

Wie Niklas darauf hingewiesen hat, funktioniert dies nicht, wenn Ihre Werte möglicherweise Listen sein könnten. Sie müssen in diesem Fall vorsichtig sein, nur in seit 'apple' in 'pineapple' == True zu verwenden. Wenn man also einen Listenverständnisansatz verfolgt, ist eine Typüberprüfung erforderlich.So können Sie eine Hilfsfunktion wie verwenden:

def equals_or_in(target, value): 
    """Returns True if the target string equals the value string or, 
    is in the value (if the value is not a string). 
    """ 
    if isinstance(target, str): 
     return target == value 
    else: 
     return target in value 

Dann unten die Liste Verständnis funktionieren würde:

my_dict = {'fruit':['apple', 'banana'], 'colour':'blue'} 
print [key for key, value in my_dict.items() if equals_or_in('apple', value)] 
+0

Ich glaube, OP will die Werte nicht die Schlüssel suchen. – Amjith

+0

@Amjith Ja, ich hatte ein Gehirn furzen. Es wurde behoben. – Wilduck

+0

Funktioniert nicht in dem allgemeineren zweiten Beispiel –

3

Ihre Anforderungen komplexer sind, als Sie denken:

  • Sie benötigen um sowohl Listenwerte als auch einfache Werte zu behandeln
  • Sie müssen nicht wirklich einen Schlüssel zurückbekommen, sondern eine Liste der Schlüssel

Sie könnten dies in zwei Schritten lösen:

  1. die dict normalisieren, so dass jeder Wert eine Liste ist (jeder Ebene Wert wird zu einem einzigen Element)
  2. ein Reverse-Wörterbuch bauen

folgende Funktionen werden dieses Problem lösen:

from collections import defaultdict 

def normalize(d): 
    return { k:(v if isinstance(v, list) else [v]) for k,v in d.items() } 

def build_reverse_dict(d): 
    res = defaultdict(list) 
    for k,values in normalize(d).items(): 
     for x in values: 
      res[x].append(k) 
    return dict(res) 

Um wie folgt verwendet werden:

>>> build_reverse_dict({'fruit':'apple','colour':'blue','meat':'beef'}) 
{'blue': ['colour'], 'apple': ['fruit'], 'beef': ['meat']} 
>>> build_reverse_dict({'fruit':['apple', 'banana'], 'colour':'blue'}) 
{'blue': ['colour'], 'apple': ['fruit'], 'banana': ['fruit']} 
>>> build_reverse_dict({'a':'duplicate', 'b':['duplicate']}) 
{'duplicate': ['a', 'b']} 

So bauen Sie genau das Gegenteil Wörterbuch einmal und dann von Wert Nachschlag und eine Liste der Schlüssel zurück.

+0

Ich denke, es gibt einen Tippfehler bei 'res [x]', da du 'x' noch nie definiert hast. – Hooked

+0

@Hooked: Danke, in der Tat, ich habe es bearbeitet, um es kürzer zu machen und es dadurch zu brechen ... –

Verwandte Themen