2012-09-25 20 views
7

Sto cercando di scrivere una lista di una lista in un nuovo file, ma sto ottenendo questo errore:TypeError: atteso un oggetto buffer di caratteri

Traceback (most recent call last): File "", line 1, in dowork() File "C:\Python27\work\accounting\formatting quickbooks file\sdf.py", line 11, in dowork WriteFile() File "C:\Python27\work\accounting\formatting quickbooks file\sdf.py", line 71, in WriteFile f.write(thefile) TypeError: expected a character buffer object

Come faccio a scrivere un elenco di un elenco di un file?

questo è come mi sto scrivendo:

def WriteFile(): 
    global thefile 
    f = open("output"+'.csv','w') 
    f.seek(0) 
    f.write(thefile) 
    f.close() 

e qui è la sorgente completo in caso di necessità:

import csv 

thefile = [] 
output = [] 

def dowork(): 
    sourceFile='e.csv' 
    thefile=ReadFile(sourceFile) 
    CleanFile(sourceFile) 
    ProcessFile() 
    WriteFile() 

def ReadFile(filename): 
    return list(csv.reader(open(filename, 'rb'), delimiter=',', quotechar='"'))[1:] 

def CleanFile(sourceFile): 
    global thefile 
    thefiletmp=[] 
    for i, line in enumerate(thefile): 
     if line[2]=='': 
      del thefile[i] 
     else: 
      thefiletmp.append(line[4:]) 
    thefile=thefiletmp 


def ProcessFile(): 
    global thefile 
    iCompany=1 
    iNum=0 
    iDate=2 
    iAging=3 
    iBalance=4 
    COMPANIES=GetDistinctValues(1) 
    mytemparray=[] 
    mytempfile=[] 
    for company in COMPANIES: 
     for line in thefile: 
      if line[iCompany]==company: 
       mytemparray.append(line[iCompany]) 
       mytemparray.append(line[iNum]) 
       mytemparray.append(line[iDate]) 
       if line[2] in range(0,31): 
        mytemparray.append(line[iBalance]) 
        mytemparray.append('0') 
        mytemparray.append('0') 
        mytemparray.append('0') 
       if line[2] in range(31,61): 
        mytemparray.append('0') 
        mytemparray.append(line[iBalance]) 
        mytemparray.append('0') 
        mytemparray.append('0') 
       if line[2] in range(61,91): 
        mytemparray.append('0') 
        mytemparray.append('0') 
        mytemparray.append(line[iBalance]) 
        mytemparray.append('0') 
       if line[2] >90: 
        mytemparray.append('0') 
        mytemparray.append('0') 
        mytemparray.append('0') 
        mytemparray.append(line[iBalance]) 
       mytempfile.append(mytemparray) 
       mytemparray=[] 
    thefile=mytempfile 

def WriteFile(): 
    global thefile 
    f = open("output"+'.csv','w') 
    f.seek(0) 
    f.write(thefile) 
    f.close() 

def GetDistinctValues(theColumn): 
    return sorted(list(set(line[theColumn] for line in thefile))) 
+0

Dovresti davvero sostituire la variabile globale con una variabile che passi a ciascuna funzione e chiudere i file quando hai finito con loro. E ora che possiamo vedere l'intero codice, ti consiglio caldamente di riorganizzarlo in modo da avere una funzione 'ProcessLine' (puoi semplicemente invertire i cicli' line' e 'company'), e solo filtrare riga per riga, quindi non è necessario un elenco e non è necessario rimuovere elementi dall'elenco sul posto e così via. Il tutto sarebbe molto più semplice in questo modo. – abarnert

+0

possibile duplicato di [TypeError: previsto un oggetto buffer di caratteri - durante il tentativo di salvare un intero in file di testo] (http: // stackoverflow.it/questions/9786941/typeerror-expected-a-character-buffer-object-while-trying-to-save-integer-to) –

risposta

12

Ciò che il messaggio di errore dice è che non è possibile scrivere una lista su un file, solo "un oggetto buffer di caratteri", che significa una stringa o qualcos'altro che agisce molto come una stringa.

Se si vuole solo scrivere l'elenco per il file nello stesso modo li ci si stampano alla console, è possibile scrivere o str(thefile)repr(thefile) (o anche utilizzare la sintassi di reindirizzamento in print invece di utilizzare file.write).

Ma si sta utilizzando il modulo csv per leggere l'input e presumibilmente si desidera l'output nello stesso formato, quindi probabilmente si desidera utilizzare anche csv per scriverlo.

Stai leggendo in questo modo:

list(csv.reader(open(filename, 'rb'), delimiter=',', quotechar='"'))[1:] 

Così scrivono in questo modo:

csv.writer(open('foo.csv', 'wb'), delimiter=',', quotechar='"').writerows(thefile) 

Devo dire che non avrei strutturare il codice come questo, in primo luogo; Vorrei fare qualcosa del genere:

with open('input.csv', 'rb') as infile, open('output.csv', 'wb') as outfile: 
    incsv = csv.reader(infile, delimiter=',', quotechar='"') 
    outcsv = csv.writer(outfile, delimiter=',', quotechar='"') 
    incsv.read() # skip first line 
    for line in incsv: 
    if line[3] != '': 
     outcsv.write(ProcessLine(line)) 
+0

+1 quello che è veramente voluto. –

3

Non si può scrivere una lista in un file; puoi solo scrivere una stringa. Converti l'elenco in una stringa in qualche modo, oppure esegui iterazioni sull'elenco e scrivi un elemento alla volta. Oppure stai usando il modulo csv, usalo per scrivere sul file.

Calling qualcosa di diverso da un file (ad esempio un elenco) thefile è destinato a portare a confusione, proprio a proposito.

+0

Ha, mi arrendo, hai vinto: D –

+0

TypeError: sequenza articolo 0: stringa attesa , lista trovata –

+0

grazie, puoi dirmi come posso usare il modulo csv per scrivere? –

2

thefile è un elenco di elenchi, non un buffer di caratteri.

for sublist in thefile: 
    f.write("".join(sublist)) # perhaps 

c'è qualche male qui, utilizzando globale, nominando un elenco thefile, ...

(la risposta corretta è abarnert di).

Problemi correlati