Pythonを使って、文字列から特定の文字を削除しようとしています。これは私が今使っているコードです。残念ながら文字列には何もしていないように見えます。
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
どのようにすれば適切にできるのでしょうか?
Pythonの文字列はimmutable(変更できない)です。 このため、line.replace(...)
の効果は、古い文字列を変更するのではなく、新しい文字列を作成するだけです。 これらの文字を削除した新しい値を変数に持たせるためには、line
に再バインド(代入)する必要があります。
また、あなたがやっている方法は、比較的、時間がかかります。 二重に入れ子になった構造を見て、何かもっと複雑なことが起きているのではないかと一瞬思ってしまうからです。
Python 2.6以降のPython 2.xバージョンでは、代わりにstr.translate
を使用することができます(ただし、Python 3の違いについてはこちらをご覧ください)。
line = line.translate(None, '!@#$')
または、re.sub
による正規表現の置き換え。
import re
line = re.sub('[!@#$]', '', line)
括弧で囲まれた文字は、文字クラスを構成しています。 lineに含まれる文字のうち、そのクラスに属するものは、
sub` の 2 番目のパラメータである空の文字列に置き換えられます。
Python 3では、文字列はUnicodeです。kevpieが回答のコメントでこのことに触れていますし、document for str.translate
にも書かれています。
Unicode文字列のtranslate
メソッドを呼び出すときに、上で使った2番目のパラメータを渡すことはできません。また、最初のパラメータとして None
を渡すこともできませんし、string.maketrans
の翻訳テーブルを渡すこともできません。代わりに、唯一のパラメータとして辞書を渡します。この辞書は、文字の ordinal value (すなわち、文字に対して ord` を呼び出した結果)を、それらを置き換えるべき文字の ordinal value にマッピングします。
つまり、ユニコード文字列で上記のダンスを行うには、次のように呼び出します。
translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)
ここでは、dict.fromkeys`とmap`を使って、以下を含む辞書を簡潔に生成しています。
{ord('!'): None, ord('@'): None, ...}
もっと単純に、別の回答ではのように、その場で辞書を作成します。
unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})
* 以前のPythonとの互換性のために、None
の代わりに "null" の翻訳テーブルを作成して渡すことができます。
import string
line = line.translate(string.maketrans('', ''), '!@#$')
ここでは string.maketrans` を使って 翻訳テーブル を作成していますが、これは単に序数が 0 から 255 の文字を含む文字列です。