ha già ricevuto risposta, ma poiché diverse persone hanno menzionato l'inversione del dizionario, ecco come lo fai in una riga (assumendo la mappatura 1: 1) e alcuni vari dati 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()}
se pensi che non sia 1: 1, puoi comunque creare una ragionevole mappatura inversa con un paio di righe:
reversedict = defaultdict(list)
[reversedict[value].append(key) for key, value in mydict.iteritems()]
quanto è lento: più lento di una semplice ricerca, ma non così lento come si potrebbe pensare - su un dizionario di voci 100000 "dritto", una ricerca "veloce" (cioè cercare un valore che dovrebbe essere all'inizio nelle chiavi) era circa 10 volte più veloce di invertire l'intero dizionario e una ricerca "lenta" (verso la fine) circa 4-5 volte più veloce. Quindi dopo al massimo circa 10 ricerche, viene pagato da solo.
la seconda versione (con elenchi per articolo) richiede circa 2,5 volte la versione semplice.
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
Ha avuto anche alcuni risultati interessanti con ifilter. Teoricamente, ifilter dovrebbe essere più veloce, in quanto possiamo usare itervalues () e possibilmente non dover creare / scorrere l'intero elenco di valori. In pratica, i risultati sono stati ... strani ...
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
Quindi, per piccoli offset, è stato drammaticamente più veloce di qualsiasi versione precedente (2,36 * u * S contro un minimo di 1,48 * m * S per i casi precedenti). Tuttavia, per grandi offset vicino alla fine dell'elenco, è stato notevolmente più lento (15,1 ms contro gli stessi 1,48 mS). I piccoli risparmi nella fascia bassa non valgono il costo nella fascia alta, imho.