Pregunta

[Tenga en cuenta que esta es una pregunta diferente de la ya respondida ¿Cómo reemplazar una columna usando el módulo de escritura .csv incorporado de Python? ]

Necesito hacer una búsqueda y reemplazo (específico para una columna de URL) en un gran archivo .csv de Excel. Como estoy en las primeras etapas de tratar de enseñarme un lenguaje de script, pensé que intentaría implementar la solución en Python.

Tengo problemas cuando intento volver a escribir en un archivo .csv después de hacer un cambio en el contenido de una entrada. He leído la documentación oficial del módulo csv sobre cómo usar el escritor, pero no hay un ejemplo que cubra este caso. Específicamente, estoy tratando de realizar las operaciones de lectura, reemplazo y escritura en un ciclo. Sin embargo, no se puede usar la misma referencia de 'fila' tanto en el argumento del bucle for como en el parámetro para writer.writerow (). Entonces, una vez que he realizado el cambio en el bucle for, ¿cómo debo volver a escribir en el archivo?

editar: implementé las sugerencias de S. Lott y Jimmy, todavía el mismo resultado

edit # 2: agregué el " rb " y '' wb '' a las funciones open (), según la sugerencia de S. Lott

import csv

#filename = 'C:/Documents and Settings/username/My Documents/PALTemplateData.xls'

csvfile = open("PALTemplateData.csv","rb")
csvout = open("PALTemplateDataOUT.csv","wb")
reader = csv.reader(csvfile)
writer = csv.writer(csvout)

changed = 0;

for row in reader:
    row[-1] = row[-1].replace('/?', '?')
    writer.writerow(row)                  #this is the line that's causing issues
    changed=changed+1

print('Total URLs changed:', changed)

editar: Para su referencia, este es el nuevo rastreo completo del intérprete:

Traceback (most recent call last):
  File "C:\Documents and Settings\g41092\My Documents\palScript.py", line 13, in <module>
    for row in reader:
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
¿Fue útil?

Solución

No puede leer y escribir el mismo archivo.

source = open("PALTemplateData.csv","rb")
reader = csv.reader(source , dialect)

target = open("AnotherFile.csv","wb")
writer = csv.writer(target , dialect)

El enfoque normal para TODAS las manipulaciones de archivos es crear una COPIA modificada del archivo original. No intente actualizar los archivos en su lugar. Es solo un mal plan.


Editar

En las líneas

source = open("PALTemplateData.csv","rb")

target = open("AnotherFile.csv","wb")

El " rb " y '' wb '' son absolutamente necesarios Cada vez que los ignora, abre el archivo para leerlo en el formato incorrecto.

Debe usar " rb " para leer un archivo .CSV. No hay elección con Python 2.x. Con Python 3.x, puede omitir esto, pero use " r " explícitamente para dejarlo claro.

Debe usar " wb " para escribir un archivo .CSV. No hay elección con Python 2.x. Con Python 3.x, debe usar "w".


Editar

Parece que estás usando Python3. Deberá soltar la " b " de " rb " y "wb".

Lea esto: http://docs.python.org/3.0/ library / functions.html # open

Otros consejos

Abrir archivos csv como binarios es simplemente incorrecto. Los archivos CSV son archivos de texto normales, por lo que debe abrirlos con

source = open("PALTemplateData.csv","r")
target = open("AnotherFile.csv","w")

El error

_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

viene porque los estás abriendo en modo binario.

Cuando estaba abriendo excel csv's con python, usaba algo como:

try:    # checking if file exists
    f = csv.reader(open(filepath, "r", encoding="cp1250"), delimiter=";", quotechar='"')
except IOError:
    f = []

for record in f:
    # do something with record

y funcionó bastante rápido (estaba abriendo dos archivos csv de aproximadamente 10 MB cada uno, aunque hice esto con python 2.6, no con la versión 3.0).

Hay pocos módulos de trabajo para trabajar con archivos CSV de Excel desde Python - pyExcelerator es uno de ellos.

el problema es que estás intentando escribir en el mismo archivo del que estás leyendo. escriba en un archivo diferente y luego cámbiele el nombre después de eliminar el original.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top