уже получен ответ, но так как несколько человек упомянули обратный ход словаря, вот как вы делаете это в одну строку (при условии отображения 1: 1) и некоторые различные данные перфорации:
python 2.6:
reversedict = dict([(value, key) for key, value in mydict.iteritems()])
2,7 +:
reversedict = {value:key for key, value in mydict.iteritems()}
если вы думаете, что это не 1: 1, вы все равно можете создать разумное обратное отображение с помощью пары строк:
reversedict = defaultdict(list)
[reversedict[value].append(key) for key, value in mydict.iteritems()]
насколько это медленно: медленнее, чем простой поиск, но не так медленно, как можно было бы подумать - в «прямом» словаре на 100000 записей - «быстрый» поиск (т. Е. Поиск значения, которое должно быть в начале ключи) была примерно в 10 раз быстрее, чем обратный ход всего словаря, а «медленный» поиск (ближе к концу) примерно в 4–5 раз быстрее. Таким образом, после примерно 10 поисков он окупается.
вторая версия (со списками на элемент) занимает примерно в 2,5 раза больше, чем простая версия.
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
Также были некоторые интересные результаты с ifilter. Теоретически, ifilter должен быть быстрее, так как мы можем использовать itervalues () и, возможно, не нужно создавать / просматривать весь список значений. На практике результаты были ... странными ...
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
Таким образом, для небольших смещений это было значительно быстрее, чем в любой предыдущей версии (2.36 * u * S против минимума 1.48 * m * S для предыдущих случаев). Однако, для больших смещений в конце списка, он был значительно медленнее (15,1 мс против тех же 1,48 мс). Небольшая экономия на нижнем конце не стоит затрат на верхнем, imho.