2011-11-30 25 views
20

He escrito el código para leer un archivo CSV en un diccionario de Python, que funciona bien. Estoy tratando de devolver el diccionario a un archivo CSV. He escrito lo siguiente:Diccionario de Python a CSV

import csv 

itemDict={} 

listReader = csv.reader(open('/Users/broberts/Desktop/Sum_CSP1.csv','rU'), delimiter = ',', quotechar='|') 

for row in listReader: 
    fID = row[0] 
    fClassRange = row[1] 
    fArea = row[2] 

    if itemDict.has_key(fID): 
     itemDict[fID][fClassRange]=fArea 
    else: 
     itemDict[fID] = {'5.0 to 5.25':'','5.25 to 5.5':'','5.5 to 5.75':'','5.75 to 6.0':'','6.0 to 6.25':'','6.25 to 6.5':'','6.5 to 6.75':'','6.75 to 7.0':'','7.0 to 7.25':'','7.25 to 7.5':'','7.5 to 7.75':'','7.75 to 8.0':'','8.0 to 8.25':'',} 
     itemDict[fID][fClassRange]=fArea 

listWriter = csv.writer(open('/Users/broberts/Desktop/Sum_CSP1_output.csv', 'wb'), delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) 

for a in itemDict: 
    print a 
    listWriter.writerow(a) 

En el último bloque, listWriter no escribirá nada a la CSV aunque se imprimirá una. Creo que esto tiene algo que ver con el desorden de un diccionario. Realmente necesito escribir el FID y cada una de las claves asociadas con cada fID (fClassRange, por ejemplo, "5.0 a 5.25") y luego el valor fArea asociado con cada fClassRange al CSV, pero ni siquiera he llegado tan lejos en mi código ya que no puedo descifrar cómo escribir incluso el FID.

Miré en el uso de DictWriter, pero no puedo encontrar la manera de indicarle lo que los nombres de campos requeridos son.

+0

que recomendar de Kenneth Reitz [tablib] (http: // docs.python-tablib.org/en/latest/). Hace más de lo que estabas buscando aquí, así que esta no es una respuesta directa, solo quieres recomendar esta biblioteca a otros. Tiene una gran API fácil de usar y puede serializar a csv, tsv, json, yaml y xlsx sin esfuerzo. – hangtwenty

Respuesta

18

El escritor predeterminado espera una lista, por lo que no funcionará para usted. Para utilizar el dictwriter, acaba de cambiar su línea de listwriter = a esto:

listWriter = csv.DictWriter(
    open('/Users/broberts/Desktop/Sum_CSP1_output.csv', 'wb'), 
    fieldnames=itemDict[itemDict.keys()[0]].keys(), 
    delimiter=',', 
    quotechar='|', 
    quoting=csv.QUOTE_MINIMAL 
) 

O bien, puede acaba de establecer fieldnames ser fieldnames=['arbitrary','list','of','keys'] si sabe lo que se supone que los campos a ser.

+0

¡Guau, gracias! Pero ahora recibo este mensaje: ValueError: dict contiene campos que no están en los nombres de los campos: 4, 6, 3, 3, 9 – bojo

+0

@bojo ¡Vaya! Estás haciendo un dict de dicts. Para obtener los nombres de campo correctos necesita los nombres de campo * del diccionario interno *. Además, cada diccionario debe tener los mismos nombres de campo. O bien, necesita utilizar las opciones de DictWriter para nombres de campo incorrectos. He actualizado la línea para usar el diccionario correcto para obtener los nombres de los campos. –

+0

Lo siento, Spencer, sigo recibiendo el mismo mensaje de ValueError. – bojo

1

Para la posteridad:

Debe utilizar iteritems() para iterar sobre un diccionario, por lo que se convierte en la última parte

for name, values in itemDict.iteritems(): 
    print values 
    listWriter.writerow(values) 
1

Esto es lo que yo uso, es simple y funciona bien para mí. cuando se tiene sólo un diccionario, utilizar este

my_dict = {"tester": 1, "testers": 2} 
with open('mycsvfile.csv', 'wb') as f: 
    w = csv.DictWriter(f, my_dict.keys()) 
    w.writerow(dict((fn,fn) for fn in my_dict.keys())) 
    w.writerow(my_dict) 

$ cat mycsvfile.csv 
testers,tester 
2,1 

Cuando usted tiene una lista de diccionarios, como lo que se obtiene a partir de consultas SQL, lo hace de esta manera.

my_dict = ({"tester": 1, "testers": 2},{"tester": 14, "testers": 28}) 
with open('mycsvfile.csv', 'wb') as f: 
    w = csv.DictWriter(f, my_dict[0].keys()) 
    w.writerow(dict((fn,fn) for fn in my_dict[0].keys())) 
    w.writerows(my_dict) 

cat mycsvfile.csv 
testers,tester 
2,1 
28,14 
1

de una sola línea para convertir una lista de dicts a CSV, utilizando los pandas:

import pandas as pd 

mydict = [{"col1": 1000, "col2": 2000}, {"col1": 3000, "col2": 4000}] 

pd.DataFrame(mydict).to_csv('out.csv', index=False) 

Resultados:

col1,col2 
1000,2000 
3000,4000