CSV en Python agregando un retorno de carro adicional, en Windows
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.csv
con un archivo adicional \r
en 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?
Pitón 3:
csv
La documentación oficial recomienda open
insertar 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 lineterminator
el dialecto , que es '\r\n'
el dialecto predeterminado excel
en 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.reader
o 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\n
de ahí lo \r\r\n
observado en el archivo.
Vea esta respuesta anterior .
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.
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.
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'])
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 =';')