2012-09-25 62 views
7

Estoy tratando de escribir una lista de una lista en un archivo nuevo, pero estoy consiguiendo este error:TypeError: Se esperaba un objeto buffer de caracteres

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

¿Cómo se escribe una lista de una lista de ¿un archivo?

Ésta es la forma en que estoy escribiendo:

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

y aquí está el código fuente completo, si lo necesita:

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

Realmente debería reemplazar la variable global con una variable que pasa a cada función, y cerrar los archivos cuando haya terminado con ellos. Y ahora que podemos ver el código completo, recomiendo reorganizarlo para que tenga una función 'ProcessLine' (puede invertir los bucles' line' y 'company'), y filtre línea por línea, para que pueda no necesita una lista, y no necesita eliminar cosas de la lista en el lugar, y así sucesivamente. Todo sería mucho más simple de esa manera. – abarnert

+0

posible duplicado de [TypeError: se esperaba un objeto de búfer de caracteres - al intentar guardar un entero en un archivo de texto] (http: // stackoverflow.com/questions/9786941/typeerror-expected-a-character-buffer-object-while-trying-to-save-integer-to) –

Respuesta

12

Lo que el mensaje de error está diciendo es que no puede escribir una lista en un archivo, solo "un objeto de memoria de caracteres", que significa una cadena u otra cosa que se parece mucho a una cadena.

Si lo que desea es escribir la lista para el archivo de la misma manera que los había imprime en la consola, se puede escribir o str(thefile)repr(thefile) (o incluso el uso de la sintaxis de redirección en lugar de utilizar printfile.write).

Pero está utilizando el módulo csv para leer la entrada, y presumiblemente quiere la salida en el mismo formato, por lo que probablemente desee usar csv para escribirla también.

Usted está leyendo la siguiente manera:

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

Así que escribe así:

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

debería mencionar que no iba a estructurar el código como este en el primer lugar; Haría algo como esto:

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 lo que realmente se quiere. –

3

No se puede escribir una lista en un archivo; solo puedes escribir una cadena. Convierta la lista en una cadena de alguna manera, o bien itere sobre la lista y escriba un elemento a la vez. O está utilizando el módulo csv, úselo para escribir en el archivo.

Llamar a algo que no sea un archivo (como una lista) thefile puede causar confusión, por cierto.

+0

Ha, renuncio, usted gana: D –

+0

TypeError: secuencia de elemento 0: cadena esperada , list found –

+0

gracias ¿me puede mostrar cómo puedo usar el módulo csv para escribir? –

2

thefile es una lista de listas, no un búfer de caracteres.

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

hay algo de malo aquí, el uso global, el nombramiento de un thefile lista, ...

(La respuesta correcta es abarnert de).

Cuestiones relacionadas