CSV в Python с добавлением дополнительного возврата каретки в Windows - PullRequest
184 голосов
/ 07 июля 2010

В Python 2.7, работающем в Windows XP pro:

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

Почему это происходит, или это действительно желаемое поведение?

Ответы [ 7 ]

245 голосов
/ 07 июля 2010

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

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

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


Этот ответ был опубликован в 2010 году и не решает проблему в Python3.

Одним из возможных исправлений в Python3, как описано в ответе @ YiboYang, является открытие файла с параметром newline, для которого задана пустая строка:

f = open(path_to_file, 'w', newline='')
writer = csv.writer(f)
...
...
226 голосов
/ 18 июля 2013

Хотя @ 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 как двоичного формата. Я предоставляю этот ответ в качестве альтернативы для вашего рассмотрения.

48 голосов
/ 18 марта 2015

В 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 голосов
/ 07 июля 2010

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

3 голосов
/ 01 июня 2017

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

with open('file.csv','w',newline="\n") as out:
    csv_out = csv.writer(out, delimiter =';')
1 голос
/ 24 октября 2017

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

1 голос
/ 09 октября 2017

Вы можете ввести параметр 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'])
...