すでに回答されていますが、何人かの人々が辞書を逆にすることを述べたので、ここでは、1行で行う方法(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番目のバージョン(アイテムごとのリスト付き)は、シンプルバージョンの約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)。ただし、リストの終わり近くの大きなオフセットの場合、劇的に遅くなりました(同じ1.48ミリ秒に対して15.1ミリ秒)。ローエンドでのわずかな節約は、ハイエンドでのコストに見合うものではありません。