余分な改行が入る例と原因
【例】
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++とエクセルで出力ファイルを開いた際に、余分な改行が出力されていないことがわかります。



コメント