Як перетворити цей список словників у файл CSV?


160

У мене є список словників, який виглядає приблизно так:

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

Що мені робити, щоб конвертувати це у файл CSV, який виглядає приблизно так:

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

Відповіді:


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: Моє попереднє рішення не обробляє замовлення. Як зауважив Вілдук, тут більше підходить DictWriter.


11
Зауважте, що більш пітонічним способом відкриття (та закриття) файлів єwith open('people.csv', 'wb') as f: ...
gozzilli

6
Ви можете використовувати dict_writer.writeheader()замістьdict_writer.writer.writerow(keys)
megawac

8
Не працює, якщо пункт першого списку не містить усіх ключів
greg121

61
у Python 3 цеopen('people.csv', 'w')
Zev Averbach

3
set().union(*(d.keys() for d in mylist))щоб отримати всі ключі у списку (якщо у вас є деякі, у яких не всі ключі.)
Julian Camilleri

17

це коли у вас є один список словників:

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

У python 3 речі трохи відрізняються, але простіше і менш схильні до помилок. Непогано сказати CSV, що ваш файл повинен бути відкритий utf8кодуванням, оскільки це робить дані більш портативними для інших (якщо ви не використовуєте більш обмежувальне кодування, як-от 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)
  • Зауважте, що csvв python 3 потрібен newline=''параметр, інакше ви отримуєте порожні рядки у своєму CSV при відкритті в excel / opencalc.

Як варіант: я вважаю за краще використовувати обробник csv в pandasмодулі. Я вважаю, що толерантніше до питань кодування, і панди автоматично перетворюють номери рядків у CSV-файлах у правильний тип (int, float тощо) під час завантаження файлу.

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

Примітка:

  • pandas подбає про те, щоб відкрити файл для вас, якщо ви дасте йому шлях, і за замовчуванням буде utf8в python3, а також з'ясуємо заголовки.
  • фрейм даних не є такою ж структурою, як те, що дає CSV, тому ви додаєте один рядок при завантаженні, щоб отримати те саме: dataframe.to_dict('records')
  • Панди також значно полегшують порядок стовпців у вашому файлі csv. За замовчуванням вони в алфавітному порядку, але ви можете вказати порядок стовпців. За допомогою csvмодуля ванілі вам потрібно подати його OrderedDictабо вони з’являться у випадковому порядку (якщо вони працюють в python <3.5). Дивіться: Збереження порядку стовпців у Python Pandas DataFrame для отримання додаткової інформації.

7

Тому що @User та @BiXiC попросили допомоги з UTF-8 тут варіантом рішення від @Matthew. (Мені не дозволяється коментувати, тому я відповідаю.)

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

Це був би найпростіший спосіб запису даних у файл .csv


1

Ось ще одне, більш загальне рішення, припускаючи, що у вас немає списку рядків (можливо, вони не вміщуються в пам'яті) або копії заголовків (можливо, ця write_csvфункція є загальною):

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)

Примітка : конструктор OrdersDict, що використовується тут, зберігає лише порядок у python> 3.4. Якщо замовлення важливе, скористайтеся OrderedDict([('name', 'bob'),('age',25)])формою.


ніколи раніше не бачив, щоб хтось зберігав дані в генераторі - цікавий підхід.
Марк Максмайстер

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.