CSV en Python que agrega un retorno de carro adicional, en Windows

En Python 2.7 ejecutándose en 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() 

Genera un archivo, test.csv, con un extra en cada fila, así:

test.csv

 hi,dude\r\r\nhi2,dude2\r\r\n 

en lugar de lo esperado:

 hi,dude\r\nhi2,dude2\r\n 

¿Por qué está sucediendo esto, o es este realmente el comportamiento deseado?

En Windows, siempre abra sus archivos en modo binario (“rb” o “wb”) antes de pasarlos a csv.reader o csv.writer.

Aunque el archivo es un archivo de texto, las bibliotecas involucradas consideran que CSV es un formato binario , con “\ r \ n” que separa los registros. Si ese separador está escrito en modo de texto, el tiempo de ejecución de Python reemplaza el “\ n” con “\ r \ n”, por lo tanto, el “\ r \ r \ n” que observó en su archivo.

Ver esta respuesta anterior .


Esta respuesta se publicó en 2010 y no soluciona el problema en Python3.

Una de las posibles soluciones en Python3, como se describe en la respuesta de @YiboYang, es abrir el archivo con el parámetro de newline establecido como una cadena vacía:

 f = open(path_to_file, 'w', newline='') writer = csv.writer(f) ... ... 

Si bien @ john-machin da una buena respuesta, no siempre es el mejor enfoque. Por ejemplo, no funciona en Python 3 a menos que codifique todas sus entradas al escritor CSV. Además, no soluciona el problema si la secuencia de comandos desea utilizar sys.stdout como la secuencia.

En su lugar, sugiero establecer el atributo ‘lineterminator’ al crear el escritor:

 import csv import sys doc = csv.writer(sys.stdout, lineterminator='\n') doc.writerow('abc') doc.writerow(range(3)) 

Ese ejemplo funcionará en Python 2 y Python 3 y no producirá los caracteres de nueva línea no deseados. Sin embargo, tenga en cuenta que puede producir nuevas líneas no deseadas (omitiendo el carácter LF en los sistemas operativos Unix).

En la mayoría de los casos, sin embargo, creo que el comportamiento es preferible y más natural que tratar a todos los CSV como un formato binario. Ofrezco esta respuesta como una alternativa para su consideración.

En Python 3 (no he probado esto en Python 2), también puedes simplemente hacer

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

según la documentación .

Más sobre esto en la nota de pie de página del documento:

Si no se especifica newline = ”, las nuevas líneas incrustadas dentro de los campos entre comillas no se interpretarán correctamente, y en las plataformas que usan \ r \ n linendings on write extra se agregarán. Siempre debe ser seguro especificar newline = ”, ya que el módulo csv realiza su propio manejo de nueva línea (universal).

No estoy seguro de por qué está sucediendo, pero cambiar el modo de archivo de “w” a “wb” lo corrige. Ver mi respuesta a ” cómo quitar ^ M ” para más detalles.

Tienes que agregar el atributo newline = “\ n” para abrir una función como esta:

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

Puede introducir el parámetro lineterminator = ‘\ n’ en el comando 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']) 

Tenga en cuenta que si utiliza DictWriter, tendrá una nueva línea desde la función de apertura y una nueva línea desde la función de escritura. Puede usar newline = ” dentro de la función abierta para eliminar la nueva línea adicional.