wurde bereits beantwortet, aber da mehrere Leute das Umkehren des Wörterbuchs erwähnt haben, gehen Sie wie folgt in einer Zeile vor (unter der Annahme einer 1: 1-Zuordnung) und einigen verschiedenen 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 Sie der Meinung sind, dass es nicht 1: 1 ist, können Sie dennoch eine vernünftige umgekehrte Zuordnung 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 man denkt - bei einem "geraden" Wörterbuch mit 100000 Einträgen eine "schnelle" Suche (dh Suche nach einem Wert, der früh in den Tasten sein sollte) war ungefähr 10x schneller als das Umkehren des gesamten Wörterbuchs und eine "langsame" Suche (gegen Ende) ungefähr 4-5x schneller. Nach höchstens 10 Suchvorgängen hat es sich also bezahlt gemacht.
Die zweite Version (mit Listen pro Element) dauert etwa 2,5-mal so lange wie 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 () verwenden können und möglicherweise nicht die gesamte Werteliste erstellen / durchgehen müssen. In der Praxis waren die Ergebnisse ... seltsam ...
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
Für kleine Offsets war es also dramatisch schneller als jede frühere Version (2,36 * u * S gegenüber einem Minimum von 1,48 * m * S für frühere Fälle). Bei großen Offsets gegen Ende der Liste war sie jedoch dramatisch langsamer (15,1 ms gegenüber denselben 1,48 ms). Die kleinen Einsparungen am unteren Ende sind die Kosten am oberen Ende nicht wert, imho.