2009-06-19 17 views
7

[Tenga en cuenta que esta es una cuestión diferente de la que ya contestado How to replace a column using Python’s built-in .csv writer module?]Escribir con Python módulo incorporado .csv

Necesito hacer una búsqueda y reemplazo (específico de una columna de URLs) en una enorme Archivo Excel .csv Como estoy en las etapas iniciales de tratar de enseñarme un lenguaje de scripting, pensé que trataría de implementar la solución en python.

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

edición: he implementado las sugerencias de S. Lott y Jimmy, sigue siendo el mismo resultado

edición # 2: añadí el "RB" y "wb" a la intemperie() funciones, por 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) 

edición: Para su referencia, esta es la nueva 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?) 

Respuesta

10

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 la manipulación de todos los 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 leer en el formato incorrecto.

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

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


Editar

Parece que está utilizando python3. Tendrás que soltar la "b" de "rb" y "wb".

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

+0

Muy bien, yo también me ocupé de ese tema. Parece que nos estamos acercando ... La trazabilidad se acortó :) – ignorantslut

+0

Ahora que lo pienso, antes de intentar volver a escribir en el archivo (es decir, cuando aún estaba trabajando para encontrar la columna de la derecha en el .csv), el script funcionaba bien sin el rb. – ignorantslut

+2

"El" rb "y" wb "son absolutamente necesarios.": No en Python 3. Allí, debe llamar a open() con newline = ''. – Miles

2

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

4

csv Apertura como binario es simplemente incorrecto. CSV son archivos de texto normales Así que hay que 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 se están abriendo en modo binario.

Cuando estaba abriendo excel de csv con Python, he usado 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 (que estaba abriendo dos acerca de 10MB cada archivo csv, aunque lo hice con Python 2.6, no se la versión 3.0).

Hay pocos módulos que funcionan para trabajar con archivos excel csv dentro de python - pyExcelerator es uno de ellos.

+1

(1) El consejo sobre la apertura de archivos es bastante incorrecto. Para Python 2.x, use "rb" o "wb" según corresponda. Para Python 3.x para leer, especifique newline = '' (2) No entiendo "Hay pocos módulos que funcionan para trabajar con archivos excel csv desde dentro de python". Hay uno, el módulo csv. ¿Cuál es la relevancia de pyExcelerator? –

+0

John, estoy 100% seguro de que cuando estaba trabajando con archivos csv con Python 2.6, los abrí en texto, no en modo binario. Abrí y traté de abrir uno ahora en Python 2.6.2. Funcionó a las mil maravillas. El inglés es mi segundo idioma, por lo que mis publicaciones/comentarios suenan como si hubieran sido escritos por un adolescente borracho. Lo que quise decir con pyExcelerator es que hay pocos módulos diseñados específicamente para trabajar con archivos csv, no escribí, que estos módulos están incluidos en la distribución estándar. Salud. – zeroDivisible

+1

(1) La apertura 2.x en modo texto no funcionará correctamente si hay nuevas líneas incrustadas en sus datos. El manual dice que se abra en modo binario. ¡Solo hazlo! (2) pyExcelerator no lee ni escribe archivos csv; nuevamente pregunto: ¿Cuál es la relevancia de pyExcelerator ??? –