1. ホーム
  2. python

[解決済み] Pythonで文字列から数字以外の文字を削除するには?

2022-05-01 21:53:54

質問

文字列から数字以外のすべての文字を削除するには?

どのように解決するのですか?

Python 2.*では、圧倒的に速いアプローチは .translate メソッドを使用します。

>>> x='aaa12333bb445bb54b5b52'
>>> import string
>>> all=string.maketrans('','')
>>> nodigs=all.translate(all, string.digits)
>>> x.translate(all, nodigs)
'1233344554552'
>>> 

string.maketrans は翻訳テーブル(長さ256の文字列)を作るが、この場合、それは ''.join(chr(x) for x in range(256)) (を作るのが速いだけです;-)。 .translate は、翻訳テーブルを適用します(これは、ここでは関係ありません。 all 本質的には同一性を意味する)、そして第二引数に存在する文字を削除する -- 重要な部分である。

.translate は、Unicode 文字列(Python 3 の文字列も同様)に対して非常に異なる動作をします。 する 質問には、どのメジャーリリースのPythonに興味があるのかを明記してほしいものです!) -- これほど単純ではなく、それほど高速でもありませんが、それでもかなり使えると思います。

2.*に戻ると、パフォーマンスの差に感動します...。

$ python -mtimeit -s'import string; all=string.maketrans("", ""); nodig=all.translate(all, string.digits); x="aaa12333bb445bb54b5b52"' 'x.translate(all, nodig)'
1000000 loops, best of 3: 1.04 usec per loop
$ python -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 7.9 usec per loop

7-8倍のスピードアップなんて、並大抵のことではありませんから。 translate は知っておいて損はない。もうひとつ、人気のある非REの手法は...。

$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())'
100000 loops, best of 3: 11.5 usec per loop

は RE よりも 50% 遅いので .translate のアプローチは、一桁以上の差をつけています。

Python 3、またはUnicodeの場合、Python 3.0からPython 3.0への移行時に .translate を返すマッピング(キーは直接文字ではなく序数)。 None を削除したい。以下は、数文字を除くすべての文字を削除する場合の便利な表現方法です。

import string

class Del:
  def __init__(self, keep=string.digits):
    self.comp = dict((ord(c),c) for c in keep)
  def __getitem__(self, k):
    return self.comp.get(k)

DD = Del()

x='aaa12333bb445bb54b5b52'
x.translate(DD)

'1233344554552' . しかし、これを xx.py に入れると...。

$ python3.1 -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 8.43 usec per loop
$ python3.1 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
10000 loops, best of 3: 24.3 usec per loop

...これは、この種の削除タスクの場合、パフォーマンスの優位性が失われ、パフォーマンスが低下していることを示しています。