¿Cómo convierto esta lista de diccionarios a un archivo csv?


160

Tengo una lista de diccionarios que se parece a esto:

toCSV = [{'name':'bob','age':25,'weight':200},{'name':'jim','age':31,'weight':180}]

¿Qué debo hacer para convertir esto a un archivo csv que se parece a esto?

name,age,weight
bob,25,200
jim,31,180

posible duplicado del encabezado
SilentGhost

Respuestas:


284
import csv
toCSV = [{'name':'bob','age':25,'weight':200},
         {'name':'jim','age':31,'weight':180}]
keys = toCSV[0].keys()
with open('people.csv', 'wb') as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(toCSV)

EDITAR: Mi solución anterior no maneja el pedido. Como señaló Wilduck, DictWriter es más apropiado aquí.


11
Tenga en cuenta que una forma más pitónica de abrir (y cerrar) archivos eswith open('people.csv', 'wb') as f: ...
gozzilli

66
Puede usar en dict_writer.writeheader()lugar dedict_writer.writer.writerow(keys)
megawac

8
No funciona si el primer elemento de la lista no contiene todas las claves
greg121

61
en Python 3 esopen('people.csv', 'w')
Zev Averbach

3
set().union(*(d.keys() for d in mylist))para obtener todas las claves de la lista (si tiene algunas que no tienen todas las claves)
Julian Camilleri

17

Esto es cuando tienes una lista de diccionario:

import csv
with open('names.csv', 'w') as csvfile:
    fieldnames = ['first_name', 'last_name']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})

17

En Python 3 las cosas son un poco diferentes, pero mucho más simples y menos propensas a errores. Es una buena idea decirle al CSV que su archivo debe abrirse con utf8codificación, ya que hace que los datos sean más portátiles para otros (suponiendo que no esté utilizando una codificación más restrictiva, como latin1)

import csv
toCSV = [{'name':'bob','age':25,'weight':200},
         {'name':'jim','age':31,'weight':180}]
with open('people.csv', 'w', encoding='utf8', newline='') as output_file:
    fc = csv.DictWriter(output_file, 
                        fieldnames=toCSV[0].keys(),

                       )
    fc.writeheader()
    fc.writerows(toCSV)
  • Tenga csven cuenta que en python 3 necesita el newline=''parámetro, de lo contrario, obtendrá líneas en blanco en su CSV al abrir en excel / opencalc.

Alternativamente: prefiero usar el controlador csv en el pandasmódulo. Creo que es más tolerante a los problemas de codificación, y los pandas convertirán automáticamente los números de cadena en CSV en el tipo correcto (int, float, etc.) al cargar el archivo.

import pandas
dataframe = pandas.read_csv(filepath)
list_of_dictionaries = dataframe.to_dict('records')
dataframe.to_csv(filepath)

Nota:

  • pandas se encargará de abrir el archivo por usted si le da una ruta, y se configurará de manera predeterminada utf8en python3, y también descubrirá los encabezados.
  • un marco de datos no tiene la misma estructura que lo que le ofrece CSV, por lo que agrega una línea al cargar para obtener lo mismo: dataframe.to_dict('records')
  • pandas también hace que sea mucho más fácil controlar el orden de las columnas en su archivo csv. Por defecto, son alfabéticos, pero puede especificar el orden de las columnas. Con el csvmódulo vanilla , debe alimentarlo OrderedDicto aparecerán en un orden aleatorio (si trabaja en python <3.5). Ver: Preservar el orden de las columnas en Python Pandas DataFrame para más información.

7

Porque @User y @BiXiC pidieron ayuda con UTF-8 aquí una variación de la solución de @Matthew. (No se me permite comentar, así que estoy respondiendo).

import unicodecsv as csv
toCSV = [{'name':'bob','age':25,'weight':200},
         {'name':'jim','age':31,'weight':180}]
keys = toCSV[0].keys()
with open('people.csv', 'wb') as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(toCSV)

2
import csv

with open('file_name.csv', 'w') as csv_file:
    writer = csv.writer(csv_file)
    writer.writerow(('colum1', 'colum2', 'colum3'))
    for key, value in dictionary.items():
        writer.writerow([key, value[0], value[1]])

Esta sería la forma más sencilla de escribir datos en un archivo .csv


1

Aquí hay otra solución más general, suponiendo que no tenga una lista de filas (tal vez no quepan en la memoria) o una copia de los encabezados (tal vez la write_csvfunción sea genérica):

def gen_rows():
    yield OrderedDict(name='bob', age=25, weight=200)
    yield OrderedDict(name='jim', age=31, weight=180)

def write_csv():
    it = genrows()
    first_row = it.next()  # __next__ in py3
    with open("people.csv", "w") as outfile:
        wr = csv.DictWriter(outfile, fieldnames=list(first_row))
        wr.writeheader()
        wr.writerow(first_row)
        wr.writerows(it)

Nota : el constructor OrderedDict utilizado aquí solo conserva el orden en python> 3.4. Si el orden es importante, use el OrderedDict([('name', 'bob'),('age',25)])formulario.


Nunca vi a nadie almacenar datos en un generador antes - enfoque interesante.
Marc Maxmeister

1
import csv
toCSV = [{'name':'bob','age':25,'weight':200},
         {'name':'jim','age':31,'weight':180}]
header=['name','age','weight']     
try:
   with open('output'+str(date.today())+'.csv',mode='w',encoding='utf8',newline='') as output_to_csv:
       dict_csv_writer = csv.DictWriter(output_to_csv, fieldnames=header,dialect='excel')
       dict_csv_writer.writeheader()
       dict_csv_writer.writerows(toCSV)
   print('\nData exported to csv succesfully and sample data')
except IOError as io:
    print('\n',io)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.