余分な改行が入る例と原因
【例】
windowsの場合、csvモジュールのwriter.writerowを使用すると余分な改行が出力されてしまいます。
import csv with open("output.csv", "w") as f: writer = csv.writer(f) row = ["row1"] writer.writerow(row) row = ["row2"] writer.writerow(row)
Notepad++で出力ファイルを開くと2行目と4行目に余分な改行があります。
エクセルで出力ファイルを開いた際も2行目と4行目に余分な行があります。
【原因】
- writer.writerowを使用した際、windowsの場合は末尾に’\r\n’が入ります。
- openに渡すパラメータとしてnewlineがありますがはNone(*1)となっています。Noneである場合、’\n’はシステムのデフォルトの行セパレータである’\r\n'(windowsの場合)に変換されます(*2)。
- 上記により、writer.writerowにより出力される’\r\n’の’\n’が’\r\n’に変換され、最終的に’\r\r\n’になります。
- ‘\r\r\n’のうち、1個目の’\r’が1個目の改行と解釈され、’\r\n’が2個目の改行と解釈されます。
(*1)Noneはopenの引数としてnewlineを渡さない時です。
(*2)以下はnewlineパラメータの説明です。
newline はストリームから受け取った改行文字をどのようにパースするかを決定します。
None
,''
,'\n'
,'\r'
, または'\r\n'
のいずれかを指定できます。これは以下のように動作します:組み込み関数 — Python 3.11.2 ドキュメント
- ストリームからの入力の読み込み時、newline が
None
の場合、ユニバーサル改行モードが有効になります。入力中の行は'\n'
,'\r'
, または'\r\n'
で終わり、呼び出し元に返される前に'\n'
に変換されます。''
の場合、ユニバーサル改行モードは有効になりますが、行末は変換されずに呼び出し元に返されます。その他の正当な値の場合、入力行は与えられた文字列でのみ終わり、行末は変換されずに呼び出し元に返されます。- ストリームへの出力の書き込み時、newline が
None
の場合、全ての'\n'
文字はシステムのデフォルトの行セパレータos.linesep
に変換されます。 newline が''
または'\n'
の場合は変換されません。newline がその他の正当な値の場合、全ての'\n'
文字は与えられた文字列に変換されます。
対策
openのnewlineパラメータを”とすることで余分な改行は出力されません。
writer.writerowにより出力される’\r\n’が’\r\r\n’に変換されなくなるためです。
import csv with open("output.csv", "w", newline='') as f: writer = csv.writer(f) row = ["row1"] writer.writerow(row) row = ["row2"] writer.writerow(row)
Notepad++とエクセルで出力ファイルを開いた際に、余分な改行が出力されていないことがわかります。
コメント