2009-06-19 23 views
7

[Si prega di notare che questa è una domanda diversa da quella già risposto How to replace a column using Python’s built-in .csv writer module?]Scrivere con di Python modulo incorporato .csv

ho bisogno di fare una ricerca e sostituzione (specifico per una colonna di URL) in un enorme File .csv di Excel. Dato che sono nelle fasi iniziali del tentativo di insegnarmi un linguaggio di scripting, ho pensato di provare a implementare la soluzione in python.

Ho problemi quando cerco di scrivere di nuovo in un file .csv dopo aver effettuato una modifica il contenuto di una voce. Ho letto il official csv module documentation su come utilizzare lo scrittore, ma non c'è un esempio che riguardi questo caso. Nello specifico, sto cercando di ottenere le operazioni di lettura, sostituzione e scrittura eseguite in un ciclo. Tuttavia, non è possibile utilizzare lo stesso riferimento di "riga" in entrambi gli argomenti del ciclo for e come parametro per writer.writerow(). Quindi, una volta apportata la modifica al ciclo for, come dovrei scrivere di nuovo sul file?

edit: ho implementato i suggerimenti da S. Lott e Jimmy, ancora lo stesso risultato

Edit # 2: ho aggiunto il "rb" e "wb" al open() funzioni, per suggerimento di 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) 

edit: Per il vostro riferimento, questa è la nuova traceback completo dall'interprete:

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?) 

risposta

10

Non è possibile leggere e scrivere lo stesso file.

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

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

L'approccio normale alla manipolazione di TUTTI i file consiste nel creare un COPY modificato del file originale. Non provare ad aggiornare i file sul posto. È solo un brutto piano.


Modifica

Nelle linee

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

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

Il "RB" e "wb" sono assolutamente necessari. Ogni volta che li ignori, apri il file per leggerlo nel formato sbagliato.

È necessario utilizzare "rb" per leggere un file .CSV. Non c'è scelta con Python 2.x. Con Python 3.x, puoi ometterlo, ma usa "r" esplicitamente per renderlo chiaro.

È necessario utilizzare "wb" per scrivere un file .CSV. Non c'è scelta con Python 2.x. Con Python 3.x, devi usare "w".


Modifica

Sembra che tu stia utilizzando python3. Dovrai rilasciare la "b" da "rb" e "wb".

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

+0

OK, mi sono occupato anche di questo problema. Sembra che ci stiamo avvicinando ... Il traceback si è accorciato :) – ignorantslut

+0

Ora che ci penso, però, prima che tentassi di riscrivere il file (cioè, mentre stavo ancora lavorando per trovare la colonna giusta in il .csv), lo script ha funzionato bene senza il rb. – ignorantslut

+2

"I" rb "e" wb "sono assolutamente necessari.": Non in Python 3. Lì, dovresti chiamare open() con newline = ''. – Miles

2

il problema è che si sta cercando di scrivere sullo stesso file che si sta leggendo. scrivere su un file diverso e quindi rinominarlo dopo aver cancellato l'originale.

4

file CSV come apertura binario è semplicemente sbagliato. CSV sono normali file di testo quindi è necessario aprirli con

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

L'errore

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

viene perché Tu li sta aprendo in modalità binaria.

Quando stavo aprendo CSV Excel di con Python, ho usato qualcosa come:

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 

e ha funzionato piuttosto veloce (stavo aprendo due circa 10 MB ogni file csv, anche se ho fatto questo con Python 2.6, non la versione 3.0).

Esistono pochi moduli di lavoro per lavorare con i file excel csv all'interno di python - pyExcelerator è uno di questi.

+1

(1) Il consiglio sull'apertura dei file è abbastanza scorretto. Per Python 2.x, utilizzare "rb" o "wb" come appropriato. Per Python 3.x per la lettura, specificare newline = '' (2) Non capisco "Esistono pochi moduli di lavoro per lavorare con i file csv di Excel all'interno di python". Ce n'è uno, il modulo csv. Qual è la rilevanza di pyExcelerator ?? –

+0

John, sono sicuro al 100% che quando stavo lavorando con file csv con python 2.6, li ho aperti nel testo, non in modalità binaria. Ho aperto il tentativo di aprirne uno ora in Python 2.6.2: funzionava come un incantesimo. L'inglese è la mia seconda lingua, quindi i miei post/commenti di solito suonano come se fossero stati scritti da Teenager ubriaco. Quello che intendevo con pyExcelerator è che ci sono pochi moduli progettati specificamente per lavorare con file CSV - non ho scritto, che questi moduli sono inclusi nella distribuzione standard. Saluti, amico. – zeroDivisible

+1

(1) 2.x l'apertura in modalità testo non funzionerà correttamente se sono presenti nuove righe incorporate nei dati. Il manuale dice di aprire in modalità binaria. Fallo! (2) pyExcelerator non legge né scrive file CSV; di nuovo chiedo: qual è la rilevanza di pyExcelerator ??? –