WindowsでのPythonでのCSVによるキャリッジリターンの追加


232
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()

次のように、各行にtest.csv追加のファイルが生成されます\r

test.csv

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

期待される代わりに:

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

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

注意:

  • この現象は、Python 2または3で発生する可能性があります。

回答:


311

Python 3:

with open('output.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    ...
with open('output.csv', 'w', newline='\n', encoding='utf-8') as f:
    writer = csv.writer(f)
    ...

Python 2:

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

ファイルはテキストファイルですが、CSVは関連するライブラリによってバイナリ形式と見なされ、\r\nレコードが分離されます。そのセパレータはテキストモードで記述されている場合は、Pythonのランタイムが代わる\n\r\n、したがって、\r\r\nファイルに観察しました。

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


3
これはASCIIでは問題ありませんが、UTF-8のようなエンコーディングを強制終了します。以下のジェイソンの解決策は私のために働いた。
トム・

66
Python 3では、ファイルオブジェクトに次のオプションを使用して修正できましたopen(..., "w", newline="\n", encoding="utf-8")newline空の文字列でもかまいませんが、同じ結果になります。"wb"Python 3では機能しません。文字列とバッファインターフェースには互換性がありません。
CodeManX

余分なキャリッジリターンを処理するエレガントな方法
ForeverLearner

2
:あなたはジェイソン・R・クームス@によって与えられた答えを使用、2と3の両方に対応する必要がありそうだとすれば、Python2で仕事をしないwriter = csv.writer(f, lineterminator='\n')
yossiz74

4
これは、必要に応じて、このような、基本的な共通とシンプルなAPIが仕事をしないことを本当の恥である
SomethingSomething

248

一方で@ジョン-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をバイナリ形式として処理するよりも、動作は望ましいものであり、より自然であると思います。私はあなたの検討の代わりとしてこの答えを提供します。


6
これは私の意見では最良の答えです。Unixでは問題があるので、sys.platformを呼び出して動的に処理するのはどうでしょうか。
2014

4
私の意見でも最良の回答です。lineterminator= '\ n'は美しく機能します。
eikonal

1
「すべての入力をCSVライターにエンコードしない」場合に発生する問題の例を挙げていただけますか?
スティーブン

注意:この手段の使用\rはもはや回避されません!これはのバグのようですcsvwriterが、現状では、準拠していない CSVを出力することは、これが適切な方法ではないことを意味します。
flow2k

これ^Mは私にとって問題を解決しましたが、受け入れられた回答の2つの提案は機能しませんでした。
user985366

55

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

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

ドキュメントに従って。

詳細については、ドキュメントの脚注をご覧ください。

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


2
@イボヤン、あなたは私に多くの時間を節約しました。
2016

4
すごい。私はpython 3.5でこの方法を確認しました
jef '26

なぜこれがデフォルトの動作にならないのですか?
マルク・ストーバー

6

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
Python 3.5.2では、これが私に有効な唯一の方法でした(まあ、私はちょうど使用しましたlineterminator='\n')。CSVモジュールがの起源であるように思われました\r\nopen影響を与える一連の引数はありません。
トミー

5

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


3

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

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

2

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.