CSV в Python добавляет дополнительный возврат каретки в Windows

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.

Ответ 1

Python 3:

  • Как описано YiboYang, установите newline=''
with open('output.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    ...
  • Как отмечено в комментариях CoDEmanX, установите newline='\n'
with open('output.csv', 'w', newline='\n', encoding='utf-8') as f:
    writer = csv.writer(f)
    ...

Python 2:

В Windows всегда открывайте файлы в двоичном режиме ("rb" или "wb"), прежде чем передавать их в csv.reader или csv.writer.

Хотя файл представляет собой текстовый файл, CSV считается вовлеченным библиотеками в двоичный формат с разделением записей \r\n. Если этот разделитель записан в текстовом режиме, среда выполнения Python заменяет \n на \r\n, следовательно, \r\r\n наблюдается в файле.

Смотрите этот предыдущий ответ.

Ответ 2

Хотя @john-machin дает хороший ответ, это не всегда лучший подход. Например, он не работает на Python 3, если вы не кодируете все ваши входы в CSV-записи. Кроме того, он не решает проблему, если скрипт хочет использовать 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 и не будет создавать нежелательные символы новой строки. Обратите внимание, однако, что это может привести к нежелательным переводам строк (исключая символ LF в операционных системах Unix).

Однако в большинстве случаев я считаю, что поведение предпочтительнее и естественнее, чем обработка всего CSV как двоичного формата. Я предоставляю этот ответ в качестве альтернативы вашему рассмотрению.

Ответ 3

В Python 3 (я не пробовал это в Python 2), вы также можете просто сделать

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

согласно документации.

Подробнее об этом в документе сноска:

Если newline = '' не указывается, новые строки, встроенные в поля, указанные в кавычках не будут правильно интерпретироваться и на платформах, которые используют \r\n будут добавлены вклады для записи дополнительного \r. Это всегда должно быть безопасно указывать newline = '', так как модуль csv делает свои собственные (универсальная) обработка новой строки.

Ответ 4

Я точно не знаю, почему это происходит, но изменение вашего файлового режима с "w" на "wb" исправляет его. Для получения более подробной информации см. Мой ответ на как удалить ^ M".

Ответ 5

Вам нужно добавить атрибут newline = "\n", чтобы открыть такую ​​функцию:

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

Ответ 6

Вы можете ввести параметр lineterminator = '\n' в команде csv writer.

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'])

Ответ 7

Обратите внимание, что если вы используете DictWriter, у вас будет новая строка из функции open и новая строка из функции writow. Вы можете использовать newline = '' внутри функции open, чтобы удалить дополнительную строку новой строки.