CSVファイルを入出力する際は、newlineオプションを指定する必要があります。
Python
1with open('villains','wt', newline='') as fout:
2 csvout = csv.writer(fout)
3 csvout.writerows(villains)
####csv.reader(csvfile, dialect='excel', **fmtparams)
与えられた csvfile 内の行を反復処理するような reader オブジェクトを返します。 csvfile はイテレータ(iterator)プロトコルをサポートし、 next() メソッドが呼ばれた際に常に文字列を返すような任意のオブジェクトにすることができます — ファイルオブジェクト でもリストでも構いません。csvfile がファイルオブジェクトの場合、 newline='' として開くべきです[1]。
####csv.writer(csvfile, dialect='excel', **fmtparams)
ユーザが与えたデータをデリミタで区切られた文字列に変換し、与えられたファイルオブジェクトに書き込むための writer オブジェクトを返します。 csvfile は write() メソッドを持つ任意のオブジェクトです。 csvfile がファイルオブジェクトの場合、 newline='' として開くべきです [1]。
####脚注
[1] newline='' が指定されない場合、クォートされたフィールド内の改行は適切に解釈されず、書き込み時に \r\n を行末に用いる処理系では余分な \r が追加されてしまいます。csv モジュールは独自 (universal newlines) の改行処理を行うため、newline='' を指定することは常に安全なはずです。
引用元: Python 標準ライブラリ » csv — CSV ファイルの読み書き
実験1
Python
1import csv
2import io
3import os
4
5
6data = [
7 [1, 2], [3, 4]
8]
9
10# OS標準の改行文字を指定した場合
11out1 = io.StringIO(newline=os.linesep)
12csv.writer(out1).writerows(data)
13
14print(
15 ' '.join(
16 ch.encode().hex() for ch in out1.getvalue()
17 )
18)
19
20# 空文字列を指定した場合
21out2 = io.StringIO(newline='')
22csv.writer(out2).writerows(data)
23
24print(
25 ' '.join(
26 ch.encode().hex() for ch in out2.getvalue()
27 )
28)
実行結果1 (手元のWindows)
cmd
1C:...>ver
2Microsoft Windows [Version 10.0.17134.523]
3
4C:...>python --version
5Python 3.6.7 :: Anaconda, Inc.
6
7C:...>python tera.py
831 2c 32 0d 0d 0a 33 2c 34 0d 0d 0a
931 2c 32 0d 0a 33 2c 34 0d 0a
実行結果2 Wandbox (Linux)
31 2c 32 0d 0a 33 2c 34 0d 0a
31 2c 32 0d 0a 33 2c 34 0d 0a
0dが復帰文字、0aが改行文字です。
実験2
Python
1import csv
2
3src = '\x0d' * 10
4data = list(csv.reader(src))
5
6print(data)
実行結果 (Windows)
C:...>python tera.py
[[], [], [], [], [], [], [], [], [], []]
復帰文字が癌になっていることが分かります。
コードの書き方について
teratailには、コードを見やすく表示する機能があります。
質問編集画面を開き、コードを選択した状態で<code>ボタンを押してください。
特にPythonの場合、インデントが崩れるとコードの意味が変わってしまいます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。