2011-12-31 10 views
53

Mam słownika:Python: Napisanie słownika do pliku CSV z jednej linii dla każdego klucza: „value”

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

Chcę zapisać dane do pliku dict.csv w tym stylu:

key1: value_a 
key2: value_b 
key3: value_c 

pisałem:

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

Ale teraz mam wszystkie klucze w jednym rzędzie i wszystkie VALU es w następnym wierszu ..

Kiedy uda mi się napisać taki plik, chcę go również przeczytać z nowym słownikiem.

Aby wyjaśnić mój kod, słownik zawiera wartości i sygnały z tekstów i pól wyboru (przy użyciu wxpython). Chcę dodać przyciski "Zapisz ustawienia" i "Wczytaj ustawienia". Zapisz ustawienia należy zapisać słownik do pliku w wymieniony sposób (aby ułatwić użytkownikowi edytować plik csv bezpośrednio), załaduj ustawienia powinny odczytać z pliku i zaktualizować textctrls i pola wyboru.

+1

czy możesz podać lepszy przykład tego, co chcesz wydrukować? "Styl", który masz powyżej, nie jest CSV. szukasz klucza key1, value_a [linebreak] key2, value_b [linebreak] key3, value_c'? – tkone

+0

Innym podejściem jest użycie 'repr()' do napisania dyktanda, a następnie eval napisu, kiedy go czytasz. Spójrz na to [stary wpis SO] (http://stackoverflow.com/questions/1436703/difference- between-str-and-repr-in-python) do dyskusji na temat 'str()' vs. 'repr()' oraz [the docs] (http://docs.python.org/library/functions.html #repr). –

+0

Oprócz mojej odpowiedzi poniżej, jeśli wolisz coś bardziej wyrafinowanego niż zwykły plik CSV, możesz chcieć sprawdzić moduł 'ConfigParser'. –

Odpowiedz

121

DictWriter nie działa zgodnie z oczekiwaniami.

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

Aby odczytać go z powrotem:

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

co jest dość zwarta, ale zakłada, że ​​nie trzeba robić żadnej konwersji typu podczas czytania

+1

Mmh ... Właśnie zauważyłem, że chciałeś określonego formatu, który nie jest dokładnie taki jak w CSV. Zakładając, że chcesz mieć styl CSV (np. Wiersz na parę klucz-wartość), ponieważ korzystasz z modułu CSV ... –

+2

Lub ... na wypadek, gdyby podejście CSV było dokładnie tym, czego potrzebujesz, ale wolisz ":" jako separator, po prostu dodaj 'delimiter = ':'' podczas tworzenia pisarza i czytnika :) –

+0

pisanie i czytanie działa teraz dobrze, ale chciałbym również zaktualizować moje pola wyboru i textctrls zgodnie z wartościami w moim słowniku. Mam wszystkie moje widżety w "def create_controls", które jest wywoływane, gdy uruchamiam mój program. Ale po prostu wywoływanie go po przeczytaniu z mojego csv nie aktualizuje stanu moich widgetów ... Czy wiesz, jaki jest najlepszy i najprostszy sposób na ich aktualizację/odświeżenie? – user1106770

2

można po prostu zrobić:

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

Tak, że można mieć

key_1: VALUE_1, key_2: wartość_2

+3

Lepiej byłoby być '','. join ("% s:% s "% (k, v) dla k, v w mydict.items())' - zwykle lepiej jest iterować nad elementami dict, które dają klucze i wartości razem, niż ponad kluczem dyktatora i wykonując wyszukiwania wartości "n". '','. join (...)' zajmuje się tylko umieszczaniem przecinków między wartościami bez dodawania dodatkowego przecinka końcowego. – PaulMcG

+0

dzięki @PaulMcGuire –

1

Ja osobiście zawsze uznało Moduł csv jest denerwujący. Spodziewam ktoś pokaże jak to zrobić slickly z nim, ale mój szybki i brudny rozwiązaniem jest:

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 

Jednakże, jeśli chcesz ją przeczytać z powrotem, trzeba zrobić trochę irytujący parsowania , zwłaszcza jeśli wszystko jest w jednym wierszu. Oto przykład użycia proponowanego formatu pliku.

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

Poszedłbym z odpowiedzią Ricarda. Lub przynajmniej użyj oddzielnych linii. –

3
outfile = open('dict.txt', 'w') 
for key, value in sorted(mydict.items()): 
    outfile.write(str(key) + '\t' + str(value) + '\n') 
+1

Proszę również podać informacje lub komentarze na temat odpowiedzi. – NDM

10

Najprostszym sposobem jest ignorowanie moduł csv i sformatować go samodzielnie.

with open('my_file.csv', 'w') as f: 
    [f.write('{0},{1}\n'.format(key, value)) for key, value in my_dict.items()] 
+4

Jeśli twój 'klucz' ma przecinek, będziesz miał zły czas. –

+2

Łatwiejsze jest użycie 'csv.writer (...) .writerows (my_dict.items())'. Moduł 'csv' robi o wiele więcej, niż tylko dodawanie przecinków i znaków nowej linii. –

2

Po prostu, aby dać opcję, pisanie słownika do pliku csv można również wykonać przy pomocy pakietu pand. Z podanym przykładzie może to być coś takiego:

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

Główną rzeczą, aby wziąć pod uwagę to, aby ustawić parametr „orient” do „index” wewnątrz metody from_dict.Dzięki temu możesz wybrać, czy chcesz pisać każdy klucz słownikowy w nowym wierszu.

Dodatkowo, w metodzie to_csv parametr nagłówka jest ustawiony na False tylko po to, aby mieć tylko elementy słownika bez irytujących wierszy. Zawsze możesz ustawić nazwy kolumn i indeksów w metodzie to_csv.

Twój wyjście będzie wyglądać następująco:

key1,a 
key2,b 
key3,c 

Jeśli zamiast tego chcesz klucze do nazw kolumnie, tuż użyć domyślnego „orient” parametr, który jest „kolumny”, jak można sprawdzić w linki do dokumentacji.

Powiązane problemy