Wie konvertiere ich diese Liste von Wörterbüchern in eine CSV-Datei?

160

Ich habe eine Liste von Wörterbüchern, die ungefähr so ​​aussieht:

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

Was soll ich tun, um dies in eine CSV-Datei zu konvertieren, die ungefähr so ​​aussieht:

name,age,weight
bob,25,200
jim,31,180
backus
quelle
Mögliches Duplikat des Schreibens des Headers in CSV-Python mit DictWriter
SilentGhost

Antworten:

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)

EDIT: Meine vorherige Lösung behandelt die Bestellung nicht. Wie von Wilduck bemerkt, ist DictWriter hier besser geeignet.

Matthew Flaschen
quelle
11
Beachten Sie, dass eine pythonischere Art des Öffnens (und Schließens) von Dateien istwith open('people.csv', 'wb') as f: ...
gozzilli
6
Sie können dict_writer.writeheader()anstelle vondict_writer.writer.writerow(keys)
Megawac
8
Funktioniert nicht, wenn das erste Listenelement nicht alle Schlüssel enthält
greg121
61
in Python 3 ist esopen('people.csv', 'w')
Zev Averbach
3
set().union(*(d.keys() for d in mylist))um alle Schlüssel in der Liste zu bekommen (wenn Sie einige haben, die nicht alle Schlüssel haben.)
Julian Camilleri
17

Dies ist, wenn Sie eine Wörterbuchliste haben:

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'})
beschämt
quelle
17

In Python 3 sind die Dinge etwas anders, aber viel einfacher und weniger fehleranfällig. Es ist eine gute Idee, der CSV mitzuteilen, dass Ihre Datei mit utf8Codierung geöffnet werden soll , da diese Daten dadurch für andere portabler werden (vorausgesetzt, Sie verwenden keine restriktivere Codierung, wie z. B. 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)
  • Beachten Sie, dass csvin Python 3 der newline=''Parameter benötigt wird, andernfalls erhalten Sie beim Öffnen in Excel / Opencalc leere Zeilen in Ihrer CSV.

Alternativ: Ich bevorzuge die Verwendung gegenüber dem CSV-Handler im pandasModul. Ich finde, es ist toleranter gegenüber Codierungsproblemen, und Pandas konvertiert beim Laden der Datei automatisch Zeichenfolgenummern in CSVs in den richtigen Typ (int, float usw.).

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

Hinweis:

  • pandas kümmert sich darum, die Datei für Sie zu utf8öffnen, wenn Sie ihr einen Pfad geben. Standardmäßig wird dies in python3 verwendet und es werden auch Header ermittelt.
  • Ein Datenrahmen hat nicht die gleiche Struktur wie CSV. Sie fügen also beim Laden eine Zeile hinzu, um dasselbe zu erhalten: dataframe.to_dict('records')
  • pandas macht es auch viel einfacher, die Reihenfolge der Spalten in Ihrer CSV-Datei zu steuern. Standardmäßig sind sie alphabetisch, Sie können jedoch die Spaltenreihenfolge angeben. Beim Vanilla- csvModul müssen Sie es füttern, OrderedDictsonst werden sie in zufälliger Reihenfolge angezeigt (wenn Sie in Python <3.5 arbeiten). Weitere Informationen finden Sie unter: Beibehalten der Spaltenreihenfolge in Python Pandas DataFrame .
Marc Maxmeister
quelle
7

Da @User und @BiXiC hier um Hilfe bei UTF-8 gebeten haben, hier eine Variation der Lösung von @Matthew. (Ich darf keinen Kommentar abgeben, also antworte ich.)

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)
Blumenblume
quelle
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]])

Dies wäre der einfachste Weg, Daten in eine CSV- Datei zu schreiben

jitsm555
quelle
1

Hier ist eine andere, allgemeinere Lösung, vorausgesetzt, Sie haben keine Liste von Zeilen (möglicherweise passen sie nicht in den Speicher) oder eine Kopie der Header (möglicherweise ist die write_csvFunktion generisch):

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)

Hinweis : Der hier verwendete OrderedDict-Konstruktor behält nur die Reihenfolge in Python> 3.4 bei. Wenn die Reihenfolge wichtig ist, verwenden Sie das OrderedDict([('name', 'bob'),('age',25)])Formular.

Eddygeek
quelle
Ich habe noch nie jemanden gesehen, der Daten in einem Generator gespeichert hat - interessanter Ansatz.
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)
Souvik Daw
quelle