Jak przekonwertować tę listę słowników do pliku CSV?


Odpowiedzi:


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)

EDYCJA: Moje poprzednie rozwiązanie nie obsługuje zamówienia. Jak zauważył Wilduck, DictWriter jest tutaj bardziej odpowiedni.


11
Zauważ, że bardziej pythonowym sposobem otwierania (i zamykania) plików jestwith open('people.csv', 'wb') as f: ...
gozzilli

6
Możesz użyć dict_writer.writeheader()zamiastdict_writer.writer.writerow(keys)
megawac

8
Nie działa, jeśli pierwsza pozycja listy nie zawiera wszystkich kluczy
greg121

61
w Pythonie 3 toopen('people.csv', 'w')
Zev Averbach

3
set().union(*(d.keys() for d in mylist))aby uzyskać wszystkie klucze z listy (jeśli masz takie, które nie mają wszystkich kluczy).
Julian Camilleri

17

tak jest, gdy masz jedną listę słowników:

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

W Pythonie 3 rzeczy są trochę inne, ale o wiele prostsze i mniej podatne na błędy. Dobrym pomysłem jest poinformowanie CSV, że plik powinien zostać otwarty z utf8kodowaniem, ponieważ sprawia, że ​​dane są bardziej przenośne dla innych (zakładając, że nie używasz bardziej restrykcyjnego kodowania, np. 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)
  • Zwróć uwagę, że csvw Pythonie 3 potrzebny jest newline=''parametr, w przeciwnym razie podczas otwierania w programie excel / opencalc otrzymasz puste wiersze w pliku CSV.

Alternatywnie: wolę używać programu obsługi csv w pandasmodule. Uważam, że jest bardziej tolerancyjny na problemy z kodowaniem, a pandy automatycznie konwertują liczby ciągów w plikach CSV na właściwy typ (int, float itp.) Podczas ładowania pliku.

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

Uwaga:

  • pandy zajmą się otwarciem pliku, jeśli podasz mu ścieżkę, i domyślnie utf8 w python3, a także ustalą nagłówki.
  • ramka danych nie jest tą samą strukturą, jaką daje CSV, więc dodajesz jedną linię po załadowaniu, aby uzyskać to samo: dataframe.to_dict('records')
  • pandy znacznie ułatwiają także kontrolowanie kolejności kolumn w pliku csv. Domyślnie są alfabetyczne, ale możesz określić kolejność kolumn. Z csvmodułem waniliowym , musisz go podać OrderedDictlub pojawią się w losowej kolejności (jeśli pracujesz w pythonie <3.5). Zobacz: Zachowywanie kolejności kolumn w Python Pandas DataFrame, aby uzyskać więcej informacji.

7

Ponieważ @User i @BiXiC poprosili o pomoc z UTF-8 tutaj wariant rozwiązania autorstwa @Matthew. (Nie mogę komentować, więc odpowiadam.)

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

Byłby to najprostszy sposób zapisania danych do pliku .csv


1

Oto inne, bardziej ogólne rozwiązanie, przy założeniu, że nie masz listy wierszy (być może nie mieszczą się w pamięci) lub kopii nagłówków (być może write_csvfunkcja jest ogólna):

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)

Uwaga : użyty tutaj konstruktor OrderedDict zachowuje tylko kolejność w Pythonie> 3.4. Jeśli zamówienie jest ważne, skorzystaj z OrderedDict([('name', 'bob'),('age',25)])formularza.


nigdy wcześniej nie widziałem nikogo, kto przechowuje dane w generatorze - ciekawe podejście.
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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.