2012-10-26 13 views
24

私はPythonが初めてです。私は、ファイルを開いて特定の単語のすべてのインスタンスをPython経由で指定した置換えに置き換えたいと考えています。たとえば、すべての単語「0」を「0」、「temp」を「bob」、「ゴミ」を「nothing」と置き換えます。ファイル内のテキストをPythonに置き換える

私が最初にこれを使用し始めていた:

for line in fileinput.input(fin): 
     fout.write(line.replace('zero', '0')) 
     fout.write(line.replace('temp','bob')) 
     fout.write(line.replace('garbage','nothing')) 

が、私は、これはこれを行うにしてもリモートで正しい方法だとは思いません。私はif文を使って行にこれらの項目が含まれているかどうかをチェックし、そうであればその行に含まれているものを置き換えようと考えましたが、Pythonについて知っているから、これも本当に理想的な解決法ではありません。私はこれを行うための最良の方法を知りたいです。あらかじめありがとう!

+0

が、これは私にこの種のものを行うためのベストプラクティスを与えるだろう:

その後
fp = open("file.txt", "w") 

fp.write(line.replace('is', 'now')) // "This is me" becomes "This now me" 

ありません。 – shadonar

+1

現在の方法では、すべての入力行が出力に3回書き込まれます。それはあなたが意図したものですか? – Junuxx

+1

また、 ''bob'の後ろにアポストロフィがありません。 – Junuxx

答えて

63

これはそれを行う必要があります

replacements = {'zero':'0', 'temp':'bob', 'garbage':'nothing'} 

with open('path/to/input/file') as infile, open('path/to/output/file', 'w') as outfile: 
    for line in infile: 
     for src, target in replacements.iteritems(): 
      line = line.replace(src, target) 
     outfile.write(line) 

EDIT:あなたは別のファイルに書き込むことなく、これを実行したい場合、Eildosa's commentに対処するために、あなたはメモリーにあなたの全体のソースファイルを読むために持ってしまいます:

lines = [] 
with open('path/to/input/file') as infile: 
    for line in infile: 
     for src, target in replacements.iteritems(): 
      line = line.replace(src, target) 
     lines.append(line) 
with open('path/to/input/file', 'w') as outfile: 
    for line in lines: 
     outfile.write(line) 

編集:あなたの代わりにreplacements.iteritems()

replacements.items()を使用して、Pythonの3.xを使用している場合
+0

'outfile.write(line)'を内側からループ...(これはOPのコードのリテラルな翻訳ですが) – mgilson

+0

ここで実際には辞書を使って(2タプルのリストとは対照的に)何を得ていますか?それは事実、あなたが 'iteritems()'を得るのは効果的です... – mgilson

+0

あなたはタプルについて正しくあります。そして、バグレポートのおかげです。 – inspectorG4dget

4

不可欠な方法は、できるだけ頻繁にあなたが必要とし、その後

  • write()として

    • read()
    • data = data.replace()です。

    データ全体を一度に、またはより小さな部分で読み書きするのはあなた次第です。予想されるファイルサイズに依存するようにする必要があります。

    read()は、ファイルオブジェクトに対する反復で置き換えることができます。

  • 6

    私はこのような何かのためにdictre.subを使用して検討するかもしれない:

    import re 
    repldict = {'zero':'0', 'one':'1' ,'temp':'bob','garage':'nothing'} 
    def replfunc(match): 
        return repldict[match.group(0)] 
    
    regex = re.compile('|'.join(re.escape(x) for x in repldict)) 
    with open('file.txt') as fin, open('fout.txt','w') as fout: 
        for line in fin: 
         fout.write(regex.sub(replfunc,line)) 
    

    これは少しより堅牢な試合を重ねるにあることにreplaceにわずかな利点があります。それを書くの

    +0

    OPが絶対的な文字列の置換をしたい場合、 're'は余計かもしれません...または何か不足していますか? – inspectorG4dget

    +3

    @ inspectorG4dget - 重複するマッチがある場合は、それが必要です。 replace( 'robert'、 'foo') ')は、' bob'を 'foo'に変更します。これは望ましくないかもしれませんが、' re'で回避することができます。また、すべてが1回実行されるので、より効率的になる可能性があります(小さなファイルでは問題はありませんが、大きなファイルでは重要ではありません)。 – mgilson

    2

    より高速な方法は...

    in = open('path/to/input/file').read() 
    out = open('path/to/input/file', 'w') 
    replacements = {'zero':'0', 'temp':'bob', 'garbage':'nothing'} 
    for i in replacements.keys(): 
        in = in.replace(i, replacements[i]) 
    out.write(in) 
    out.close 
    

    これは、他の答えが示唆繰り返しの多くを排除されるだろう、と長いファイルのためのプロセスをスピードアップします。

    +1

    しかし、それはファイル全体を読み込みます(そして、置き換えのたびにそれを複製します)。これは大きなファイルの大きな欠点です。 – mgilson

    +0

    これは本質的に@glglglによるソリューションの複製です。 – mgilson

    0

    標準入力からの読み取り、 'コード'。PY」次のように

    import sys 
    
    rep = {'zero':'0', 'temp':'bob', 'garbage':'nothing'} 
    
    for line in sys.stdin: 
        for k, v in rep.iteritems(): 
         line = line.replace(k, v) 
        print line 
    

    を次に、リダイレクトや配管でスクリプトを実行(http://en.wikipedia.org/wiki/Redirection_(computing)

    python code.py <infile> outfile 
    
    5

    をあなたのファイルが(非常に長いかさえない)が短い場合は、次のスニペットを使用することができます所定の位置にテキストを置換します

    # Replace variables in file 
    with open('path/to/in-out-file', 'r+') as f: 
        content = f.read() 
        f.seek(0) 
        f.truncate() 
        f.write(content.replace('replace this', 'with this')) 
    
    +0

    これは私のお気に入りの回答でした! – EminezArtus

    0

    これは私がちょうど使用される短いと簡単な例です:

    場合:私はもっと多くのことをやっているよ

    line.replace('is', 'now') 
    fp.write(line) 
    // "This is me" not changed while writing 
    
    関連する問題