web-dev-qa-db-ja.com

WindowsでのPythonのCSVによる余分な改行の追加

Windows XP proで実行されているPython 2.7:

import csv
outfile = file('test.csv', 'w')
writer = csv.writer(outfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
writer.writerow(['hi','dude'])
writer.writerow(['hi2','dude2'])
outfile.close()

次のように、各行に追加の\ rを含むファイルtest.csvを生成します。

test.csv

hi,dude\r\r\nhi2,dude2\r\r\n

予想される代わりに:

hi,dude\r\nhi2,dude2\r\n

なぜこれが起こっているのですか、これは実際に望ましい動作ですか?

184
apalopohapa

Windowsでは、ファイルをcsv.readerまたはcsv.writerに渡す前に、常にバイナリモード( "rb"または "wb")で開いてください。

ファイルはテキストファイルですが、CSVは関連するライブラリによってbinary形式と見なされ、「\ r\n」がレコードを区切ります。その区切り文字がテキストモードで記述されている場合、Pythonランタイムは「\ n」を「\ r\n」に置き換えます。したがって、ファイルで確認した「\ r\r\n」になります。

この前の回答 を参照してください。


この回答は2010年に投稿されたものであり、Python3の問題には対応していません。

@YiboYangの答えで説明されているように、Python3で可能な修正の1つは、newlineパラメーターを空の文字列に設定してファイルを開くことです。

f = open(path_to_file, 'w', newline='')
writer = csv.writer(f)
...
...
242
John Machin

@ john-machin は良い答えを与えますが、常に最良のアプローチとは限りません。たとえば、CSVライターへのすべての入力をエンコードしない限り、Python 3では機能しません。また、スクリプトがsys.stdoutをストリームとして使用する場合、問題に対処しません。

代わりに、ライターを作成するときに「lineterminator」属性を設定することをお勧めします。

import csv
import sys

doc = csv.writer(sys.stdout, lineterminator='\n')
doc.writerow('abc')
doc.writerow(range(3))

この例はPython 2およびPython 3で動作し、不要な改行文字を生成しません。ただし、望ましくない改行が生成される可能性があることに注意してください(UnixオペレーティングシステムではLF文字は省略されます)。

ただし、ほとんどの場合、すべてのCSVをバイナリ形式として扱うよりも、振る舞いのほうが自然で自然だと思います。私はあなたの検討のための代替としてこの答えを提供します。

223
Jason R. Coombs

Python 3(Python 2でこれを試したことはありません)では、単純に行うこともできます

with open('output.csv','w',newline='') as f:
    writer=csv.writer(f)
    writer.writerow(mystuff)
    ...

ドキュメント に従って。

詳細については、ドキュメントの footnote

Newline = ''が指定されていない場合、引用されたフィールド内に埋め込まれた改行は正しく解釈されず、書き込み時に\ r\nリンデンディングを使用するプラットフォームでは追加の\ rが追加されます。 csvモジュールは独自の(ユニバーサル)改行処理を行うため、newline = ''を指定することは常に安全である必要があります。

48
Yibo Yang

なぜそれが起こっているのか正確にはわかりませんが、ファイルモードを「w」から「wb」に変更すると修正されます。詳細については、「 ^ Mを削除する方法 」に対する回答を参照してください。

4
Ned Batchelder

次のような関数を開くには、属性newline = "\ n"を追加する必要があります。

with open('file.csv','w',newline="\n") as out:
    csv_out = csv.writer(out, delimiter =';')
3
Gregor Ažbe

DictWriterを使用する場合、open関数からの新しい行とwriterow関数からの新しい行があることに注意してください。 open関数内でnewline = ''を使用して、余分な改行を削除できます。

1
Erick Stone

Csv writerコマンドでlineterminator = '\ n'パラメーターを導入できます。

import csv
delimiter='\t'
with open('tmp.csv', '+w', encoding='utf-8') as stream:
    writer = csv.writer(stream, delimiter=delimiter, quoting=csv.QUOTE_NONE, quotechar='',  lineterminator='\n')
    writer.writerow(['A1' , 'B1', 'C1'])
    writer.writerow(['A2' , 'B2', 'C2'])
    writer.writerow(['A3' , 'B3', 'C3'])
1
Wesam Na