Как мне преобразовать этот список словарей в 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
Backus
источник
возможный дубликат написания заголовка в csv python с DictWriter
SilentGhost

Ответы:

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

РЕДАКТИРОВАТЬ: мое предыдущее решение не обрабатывает заказ. Как отмечает Уилдак, 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')
Зев Авербах
3
set().union(*(d.keys() for d in mylist))чтобы получить все ключи в списке (если у вас есть ключи, у которых не все ключи)
Джулиан Камиллери
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модуле. Я считаю, что он более терпим к проблемам кодирования, и pandas автоматически преобразует номера строк в CSV-файлах в правильный тип (int, float и т. Д.) При загрузке файла.

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

Примечание:

  • pandas позаботится об открытии файла для вас, если вы дадите ему путь, и по умолчанию будет использовать utf8python3, а также определит заголовки.
  • структура данных не такая же, как у CSV, поэтому при загрузке вы добавляете одну строку, чтобы получить то же самое: dataframe.to_dict('records')
  • Pandas также значительно упрощает управление порядком столбцов в вашем CSV-файле. По умолчанию они в алфавитном порядке, но вы можете указать порядок столбцов. С ванильным csvмодулем вам нужно кормить его OrderedDictили они появятся в случайном порядке (если работает в python <3.5). См .: Сохранение порядка столбцов в Python DataFrame Pandas для получения дополнительной информации.
Марк Максмейстер
источник
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)
flowerflower
источник
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

jitsm555
источник
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)

Примечание : используемый здесь конструктор OrderedDict сохраняет порядок только в python> 3.4. Если порядок важен, используйте OrderedDict([('name', 'bob'),('age',25)])форму.

eddygeek
источник
никогда не видел, чтобы кто-то хранили данные в генераторе - интересный подход.
Марк Максмейстер
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)
Сувик Доу
источник