TL;DR
pythonのdictのkey,valueを逆にしたものを生成したい場合は、以下が最速。
d = dict(zip(list('abc'), range(3))) # 例として適当な辞書を生成
d2 = dict(zip(d.values(), d.keys())) # 逆
本題
pythonを書いていると、既存のdictのkey,valueを逆にしたものを生成したい場合があったりします。例えば、
{'a': 0, 'b': 1, 'c': 2}
に対する
{0: 'a', 1: 'b', 2: 'c'}
です。そこで、逆版を最速で得るやり方を幾つか試してみました。
準備
d = dict(zip([f'key{i}' for i in range(10000)], range(10000))) # 適当な辞書
1. forループ
%%timeit
d2 = dict()
for k in d:
d2[d[k]] = k
結果: 1.09 ms ± 57.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
2. zipで値とキーを結合
%timeit dict(zip(d.values(), d.keys()))
結果: 525 µs ± 21.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
3. 辞書内包表記
%timeit {v:k for k,v in d.items()}
結果: 661 µs ± 23 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
結果
結果、2. zipで値とキーを結合 が最速となりました。pythonの内部の挙動は不勉強でよく分かりませんが、forループが効いているように感じます。pythonのforループは一回ごとに型チェックが入るので遅い、というのは色々な所で指摘されています。
ただ、2位である辞書内包表記とあまり差がないので、()のネストが深い分可読性が落ちることを考慮して、3.でも良いかも知れません。
以上。