アルファベットの対応する文字の位置を取得するPythonのいくつかのメソッドとパフォーマンスの比較
場合によっては、アルファベットの文字の順序、A = 1、B = 2、C = 3、を見つける必要がある場合があります。たとえば、この質問 https://projecteuler.net/problem=42 問題を解決する手順の 1 つは、文字をアルファベットの対応する順序に変換することです。
アルファベットの対応する文字の位置を取得する最も簡単な方法は次のとおりです:
str.index または str.find メソッドを使用します:
In [137]: "ABC".index('B') Out[137]: 1In [138]: "ABC".index('B')+1Out[138]: 2#或者在前面填充一个字符,这样index就直接得到字母序号: In [139]: "_ABC".index("B") Out[139]: 2
アルファベットをリストまたはタプルに変換してインデックスを付け、パフォーマンスを向上させることも考えました。改善されるでしょうか? それとも、文字と数字で構成されるキー値を辞書に保存するのが得策でしょうか?
私も 2 日前ある方法に気づきました:
In [140]: ord('B')-64 Out[140]: 2
ord と chr は両方とも Python の組み込み関数です。ord は ASCII 文字を ASCII テーブルに対応するシリアル番号に変換でき、chr はシリアル番号を文字列に変換できます。
表の大文字は 65 から始まり、マイナス 64 が表の大文字の位置と同じになります。 小文字は 97 から始まり、96 未満が対応するアルファベットの位置になります。
パフォーマンスの点ではどちらのアプローチが優れているでしょうか?テストするためのコードを書きました:
az = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"_az = "_ABCDEFGHIJKLMNOPQRSTUVWXYZ"azlist = list(az) azdict = dict(zip(az,range(1,27))) text = az*1000000 #这个是测试数据#str.find和str.index的是一样的。这里就没必要写了。def azindexstr(text): for r in text: az.index(r)+1 passdef _azindexstr(text): for r in text: _az.index(r) passdef azindexlist(text): for r in text: azlist.index(r) passdef azindexdict(text): for r in text: azdict.get(r) passdef azindexdict2(text): for r in text: azdict[r] passdef azord(text): for r in text: ord(r)-64 passdef azand64(text): for r in text: ord(r)%64 pass
上記のコードをコピーして ipython に貼り付け、マジック関数 %timeit を使用して各メソッドのパフォーマンスをテストします。 ipython は、主にテキストに使用される %timeit 関数など、非常に実用的なさまざまな関数を備えた Python 対話型インタープリターです。 インストールするには pip install ipython と入力してください
以下は私のテストの結果データです:
In [147]: %timeit azindexstr(text) 1 loop, best of 3: 9.09 s per loop In [148]: %timeit _azindexstr(text) 1 loop, best of 3: 8.1 s per loop In [149]: %timeit azindexlist(text) 1 loop, best of 3: 17.1 s per loop In [150]: %timeit azindexdict(text) 1 loop, best of 3: 4.54 s per loop In [151]: %timeit azindexdict2(text) 1 loop, best of 3: 1.99 s per loop In [152]: %timeit azord(text) 1 loop, best of 3: 2.94 s per loop In [153]: %timeit azand64(text) 1 loop, best of 3: 4.56 s per loop
結果から、list.index が最も遅いことが分かりますが、これには驚きました。さらに、リストに大量のデータがある場合、インデックスは非常に遅くなります。 dict[r] の速度は dict.get(r) の速度よりも高速ですが、存在しないキーの場合、dict[r] はエラーを報告しますが、dict.get メソッドはエラーを報告しません。より優れた耐障害性を備えています。
ord(r)-64 のメソッドは高速で、データを構築する必要がないため、最も使いやすいはずです。