Запись словаря в файл csv с одной строкой для каждого ключа: значения

92

У меня есть словарь:

mydict = {key1: value_a, key2: value_b, key3: value_c}

Я хочу записать данные в файл dict.csv в таком стиле:

key1: value_a
key2: value_b
key3: value_c

Я написал:

import csv
f = open('dict.csv','wb')
w = csv.DictWriter(f,mydict.keys())
w.writerow(mydict)
f.close()

Но теперь у меня все ключи в одной строке и все значения в следующей строке ..

Когда мне удается записать такой файл, я также хочу прочитать его обратно в новый словарь.

Чтобы объяснить мой код, словарь содержит значения и логические значения из textctrls и флажков (с использованием wxpython). Хочу добавить кнопки «Сохранить настройки» и «Загрузить настройки». Параметры сохранения должны записывать словарь в файл указанным способом (чтобы пользователю было проще редактировать файл csv напрямую), параметры загрузки должны считываться из файла и обновлять textctrls и флажки.

user1106770
источник
1
Можете ли вы предоставить лучший пример того, что вы хотите получить? "стиль", указанный выше, не является CSV. ты ищешь key1, value_a [linebreak] key2, value_b [linebreak] key3, value_c?
tkone
Другой подход состоит в том, чтобы использовать repr()для записи словаря, а затем для оценки строки, когда вы ее читаете. Посмотрите на этот старый пост SO, где обсуждаются str()vs. repr(), а также документы .
Питер Роуэлл
Помимо моего ответа ниже, если вы предпочитаете что-то более сложное, чем простой файл CSV, вы можете проверить ConfigParserмодуль
Рикардо Карденес
3
Вы описываете типичный формат CSV, записанный модулем csv. Если вы записываете несколько dict с одними и теми же ключами, ключи записываются только один раз, в первой строке, с одной строкой на каждый dict для соответствующих значений, в правильном порядке, чтобы
выровняться

Ответы:

186

DictWriterНе работает так , как вы ожидаете.

with open('dict.csv', 'w') as csv_file:  
    writer = csv.writer(csv_file)
    for key, value in mydict.items():
       writer.writerow([key, value])

Чтобы прочитать это обратно:

with open('dict.csv') as csv_file:
    reader = csv.reader(csv_file)
    mydict = dict(reader)

который довольно компактен, но предполагает, что вам не нужно выполнять преобразование типов при чтении

Рикардо Карденес
источник
2
Ммм ... Просто заметил, что вам нужен конкретный формат, который не совсем похож на CSV. Предполагается, что вам нужен стиль CSV (то есть строка для каждой пары ключ-значение), потому что вы использовали модуль CSV ...
Рикардо Карденес
3
Или ... в случае, если подход CSV - это именно то, что вы хотели, но вы предпочитаете ":" в качестве разделителя, просто добавьте delimiter=':'при создании писателя и читателя :)
Рикардо Карденес
2
Обратите внимание: вы должны закрыть файл между записью и чтением. Посмотрите, что произошло в этом вопросе / ответе: stackoverflow.com/a/38467563/235698
Марк Толонен
1
@MarkTolonen, конечно, withлучше использовать. Я изменю примеры, чтобы отразить это ...
Рикардо Карденес
1
@DareYang извините за задержку. На самом деле, я не уверен, зачем я это написал тогда. Это не нужно. При записи это приводит к тому, что символы новой строки остаются непереведенными (т. Е. Если вы пишете \n, вы попадете \nв файл). Если оставить его в покое, сработает «универсальный режим», и новые строки переводятся в значения по умолчанию для текущей операционной системы. Учитывая, что здесь это бесполезно (кроме случаев, когда вы хотите иметь предсказуемые символы новой строки), я удалю его.
Рикардо Карденес,
27

Чтобы дать возможность, запись словаря в файл csv также может быть выполнена с помощью пакета pandas. В данном примере это могло быть примерно так:

mydict = {'key1': 'a', 'key2': 'b', 'key3': 'c'}

import pandas as pd

(pd.DataFrame.from_dict(data=mydict, orient='index')
   .to_csv('dict_file.csv', header=False))

Главное, что нужно принять во внимание, - это установить для параметра 'orient' значение 'index' внутри метода from_dict . Это позволяет вам выбрать, хотите ли вы записывать каждый ключ словаря в новую строку.

Кроме того, внутри метода to_csv параметр заголовка имеет значение False, чтобы иметь только элементы словаря без раздражающих строк. Вы всегда можете установить имена столбцов и индексов внутри метода to_csv.

Ваш результат будет выглядеть так:

key1,a
key2,b
key3,c

Если вместо этого вы хотите, чтобы ключи были именами столбцов, просто используйте параметр «orient» по умолчанию, который является «columns», как вы могли бы проверить в ссылках на документацию.

Иван Кальдерон
источник
2
Отлично работал как шарм :). Мое значение было списком, и он сгенерировал мой CSV со всеми значениями списка в нескольких ячейках и сопоставлен с ключом в первом столбце.
vinsinraw
14

Самый простой способ - игнорировать модуль csv и отформатировать его самостоятельно.

with open('my_file.csv', 'w') as f:
    [f.write('{0},{1}\n'.format(key, value)) for key, value in my_dict.items()]
Фил Горовиц
источник
8
Если у вас keyесть запятая, вам будет плохо.
Али Ашраф,
5
Мне проще просто использовать csv.writer(...).writerows(my_dict.items()). csvМодуль делает это гораздо больше , чем просто добавить запятые и новую строку.
Мартейн Питерс
6
outfile = open( 'dict.txt', 'w' )
for key, value in sorted( mydict.items() ):
    outfile.write( str(key) + '\t' + str(value) + '\n' )
FCAlive
источник
1
Пожалуйста, также предоставьте некоторую информацию или комментарии к вашему ответу.
NDM
2

Вы можете просто сделать:

for key in mydict.keys():
    f.write(str(key) + ":" + str(mydict[key]) + ",");

Чтобы вы могли

ключ_1: значение_1, ключ_2: значение_2

louis.luo
источник
3
Лучше было бы ','.join("%s:%s" % (k,v) for k,v in mydict.items())- вам обычно лучше перебирать элементы dict, которые дают вам ключи и значения вместе, чем по ключам dict и выполнять поиск значений n. ','.join(...)заботится только о том, чтобы помещать запятые между значениями, без добавления дополнительной запятой.
PaulMcG
обратите внимание, что вам не понадобится точка с запятой в конце для этого кода Python
beep_check
1

Я лично всегда находил модуль csv чем-то раздражающим. Я ожидаю, что кто-то другой покажет вам, как с ним хорошо справиться, но мое быстрое и грязное решение:

with open('dict.csv', 'w') as f:  # This creates the file object for the context 
                                  # below it and closes the file automatically
    l = []
    for k, v in mydict.iteritems(): # Iterate over items returning key, value tuples
        l.append('%s: %s' % (str(k), str(v))) # Build a nice list of strings
    f.write(', '.join(l))                     # Join that list of strings and write out

Однако, если вы хотите прочитать его снова, вам нужно будет провести раздражающий синтаксический анализ, особенно если все это в одной строке. Вот пример использования предложенного вами формата файла.

with open('dict.csv', 'r') as f: # Again temporary file for reading
    d = {}
    l = f.read().split(',')      # Split using commas
    for i in l:
        values = i.split(': ')   # Split using ': '
        d[values[0]] = values[1] # Any type conversion will need to happen here
Гриффит Рис
источник
Я бы согласился с ответом Рикардо. Или хотя бы использовать отдельные строчки.
Гриффит Рис
0
import csv

dict = {"Key Header":"Value Header", "key1":"value1", "key2":"value2"}

with open("test.csv", "w") as f:
    writer = csv.writer(f)
    for i in dict:
      writer.writerow([i, dict[i]])
f.close() 

введите описание изображения здесь

Апурва Торат
источник
Я не думаю, что вам нужно явно закрывать файл в последней строке. Менеджер контекста сделает это за вас.
avaj_wen12,
0
#code to insert and read dictionary element from csv file
import csv
n=input("Enter I to insert or S to read : ")
if n=="I":
    m=int(input("Enter the number of data you want to insert: "))
    mydict={}
    list=[]
    for i in range(m):
        keys=int(input("Enter id :"))
        list.append(keys)
        values=input("Enter Name :")
        mydict[keys]=values

    with open('File1.csv',"w") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=list)
        writer.writeheader()
        writer.writerow(mydict)
        print("Data Inserted")
else:
    keys=input("Enter Id to Search :")
    Id=str(keys)
    with open('File1.csv',"r") as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            print(row[Id]) #print(row) to display all data
Ашиш Нандан
источник
Было бы лучше, если бы вы добавили небольшое пояснение
Роаим 08
-2

Вы пробовали добавить "s" на: w.writerow(mydict)вот так w.writerows(mydict):? Эта проблема случилась со мной, но со списками я использовал единственное, а не множественное число.

Хикудж
источник