CSV en Python agregando un retorno de carro adicional, en Windows

Resuelto apalopohapa asked hace 14 años • 6 respuestas
import csv

with open('test.csv', 'w') as outfile:
    writer = csv.writer(outfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
    writer.writerow(['hi', 'dude'])
    writer.writerow(['hi2', 'dude2'])

El código anterior genera un archivo, test.csvcon un archivo adicional \ren cada fila, así:

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

en lugar de lo esperado

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

¿Por qué sucede esto o es realmente el comportamiento deseado?

apalopohapa avatar Jul 07 '10 09:07 apalopohapa
Aceptado

Pitón 3:

csvLa documentación oficial recomienda openinsertar el archivo newline=''en todas las plataformas para deshabilitar la traducción universal de nuevas líneas :

with open('output.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    ...

El escritor CSV termina cada línea con lineterminatorel dialecto , que es '\r\n'el dialecto predeterminado excelen todas las plataformas porque eso es lo que recomienda RFC 4180 .


Pitón 2:

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

Aunque el archivo es un archivo de texto, las bibliotecas involucradas consideran que CSV es un formato binario\r\n , con registros separados. Si ese separador está escrito en modo texto, el tiempo de ejecución de Python reemplaza con \n, \r\nde ahí lo \r\r\nobservado en el archivo.

Vea esta respuesta anterior .

John Machin avatar Jul 07 '2010 03:07 John Machin

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 en el escritor CSV. Además, no soluciona el problema si el script quiere utilizar sys.stdout como secuencia.

En su lugar, sugiero configurar 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á 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).

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

Jason R. Coombs avatar Jul 18 '2013 13:07 Jason R. Coombs

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 documentación .

Más sobre esto en la nota al pie 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 plataformas que usan \r\n linodings al escribir, se agregará un \r adicional. Siempre debería ser seguro especificar newline='', ya que el módulo csv realiza su propio manejo (universal) de nueva línea.

Yibo Yang avatar Mar 18 '2015 07:03 Yibo Yang

Puede introducir el parámetro lineterminator='\n' en el comando del escritor csv.

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'])
Wesam Na avatar Oct 09 '2017 10:10 Wesam Na

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 =';')
Gregor Ažbe avatar Jun 01 '2017 20:06 Gregor Ažbe