python CSV出力時の余分な改行を取り除く方法

余分な改行が入る例と原因

【例】

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' のいずれかを指定できます。これは以下のように動作します:

  • ストリームからの入力の読み込み時、newline が None の場合、ユニバーサル改行モードが有効になります。入力中の行は '\n''\r', または '\r\n' で終わり、呼び出し元に返される前に '\n' に変換されます。 '' の場合、ユニバーサル改行モードは有効になりますが、行末は変換されずに呼び出し元に返されます。その他の正当な値の場合、入力行は与えられた文字列でのみ終わり、行末は変換されずに呼び出し元に返されます。
  • ストリームへの出力の書き込み時、newline が None の場合、全ての '\n' 文字はシステムのデフォルトの行セパレータ os.linesep に変換されます。 newline が '' または '\n' の場合は変換されません。newline がその他の正当な値の場合、全ての '\n' 文字は与えられた文字列に変換されます。
組み込み関数 — Python 3.11.2 ドキュメント

対策

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

コメント

タイトルとURLをコピーしました