『続・辞書のキーと値を入れ替えをPythonでやってみたの速度を計測してみた - 牌語備忘録 - pygo』の続き
『辞書のキーと値を入れ替える(2) - プログラミング日記』さんの情報からizip最強説を検証。
import timeit t= timeit.Timer(setup="dict_data = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}", stmt=""" def d_change_a(d): di = {} for k in d: di[d[k]] = k return dict(di) d_change_a(dict_data) """) print "A-1: ", t.timeit(number = 100000) t= timeit.Timer(setup="dict_data = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}", stmt=""" def d_change_a2(d): for k in d: d[d.pop(k)] = k return d d_change_a2(dict_data) """) print "A-2: ", t.timeit(number = 100000) t= timeit.Timer(setup="dict_data = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}", stmt="dict((lambda d:[(d[k], k) for k in d])(dict_data))") print "B : ", t.timeit(number = 100000) t= timeit.Timer(setup="dict_data = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}", stmt=""" def d_change_c(d): return dict([(d[k], k) for k in d]) d_change_c(dict_data) """) print "C : ", t.timeit(number = 100000) t= timeit.Timer(setup="dict_data = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}", stmt="dict((v, k) for k, v in dict_data.iteritems())") print "D : ", t.timeit(number = 100000) t= timeit.Timer(setup=""" from itertools import izip dict_data = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'} """, stmt="dict(izip(dict_data.itervalues(), dict_data.iterkeys()))") print "E : ", t.timeit(number = 100000) t= timeit.Timer(setup="dict_data = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}", stmt="dict(zip(dict_data.itervalues(), dict_data))") print "F : ", t.timeit(number = 100000)
A-1: 0.553325891495 A-2: 0.758898973465 B : 0.860321044922 C : 0.856045007706 D : 0.746444940567 E : 0.575052976608 F : 0.926265954971
辞書の要素が少ないとA-1が速い。
辞書の要素を増やしてテスト
A-1とEの辞書を5000個にしてテスト(number = 100に変更)
#辞書を5000個にしてテスト(number = 100に変更) t= timeit.Timer(setup="dict_data = dict(enumerate(range(5000)))", stmt=""" def d_change_a(d): di = {} for k in d: di[d[k]] = k return dict(di) d_change_a(dict_data) """) print "A-1: ", t.timeit(number = 100) t= timeit.Timer(setup=""" from itertools import izip dict_data = dict(enumerate(range(5000))) """, stmt="dict(izip(dict_data.itervalues(), dict_data.iterkeys()))") print "E : ", t.timeit(number = 100)
A-1: 0.333739042282 E : 0.20229101181
辞書の要素が増えるとEが最速。
結論
ということでitertoolsのizip使うのが最強みたい。
>|python
from itertools import izip
dict_data = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}
dict(izip(dict_data.itervalues(), dict_data.iterkeys()))
|
Pythonはモジュール使うのが速いみたい。
http://newworld.ddo.jp/doc/PythonSpeed
- (CPythonの)コアとなる構成要素のいくつかは、最適化されたCのコードで書かれています。このアドバンテージを利用するアプリケーションは、実質的な実行効率の向上を得ることができます。この組み込みの構成要素にはすべての組み込み型(リスト、タプル、sets、辞書)と、array、 itertools、collection.dequeのような拡張モジュールを含みます。
- 同様に、組み込み関数は手で書かれたコードより速く動作します。例えばmap(operator.add, v1, v2)はmap(lambda x,y: x+y, v1, v2)より速く動きます。