Scrittura di un dizionario in un file CSV con una riga per ogni "chiave: valore"


92

Ho un dizionario:

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

Voglio scrivere i dati su un file dict.csv, in questo stile:

key1: value_a
key2: value_b
key3: value_c

Scrissi:

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

Ma ora ho tutte le chiavi in ​​una riga e tutti i valori nella riga successiva ..

Quando riesco a scrivere un file come questo, voglio anche leggerlo su un nuovo dizionario.

Giusto per spiegare il mio codice, il dizionario contiene valori e bool da textctrls e checkboxes (usando wxpython). Voglio aggiungere i pulsanti "Salva impostazioni" e "Carica impostazioni". Le impostazioni di salvataggio dovrebbero scrivere il dizionario nel file nel modo indicato (per rendere più facile per l'utente modificare direttamente il file csv), le impostazioni di caricamento dovrebbero leggere dal file e aggiornare i textctrls e le caselle di controllo.


1
puoi fornire un esempio migliore di ciò che vuoi come output? lo "stile" che hai sopra non è CSV. stai cercando key1, value_a [linebreak] key2, value_b [linebreak] key3, value_c?
tkone

Un altro approccio è usare repr()per scrivere il dict e poi evalare la stringa quando lo leggi. Guarda questo vecchio post SO per una discussione su str()vs. repr(), e anche sui documenti .
Peter Rowell

A parte la mia risposta di seguito, se preferisci qualcosa di un po 'più sofisticato di un semplice file CSV, potresti voler controllare il ConfigParsermodulo
Ricardo Cárdenes

3
Quello che descrivi è il tipico formato CSV scritto dal modulo csv. Se scrivi più dict con le stesse chiavi, le chiavi vengono scritte solo una volta, nella prima riga, con una riga per dict per i valori corrispondenti, nell'ordine corretto per allinearsi con le chiavi nella riga 1.
PaulMcG

Risposte:


186

Il DictWriternon funziona nel modo previsto.

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

Per rileggerlo:

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

che è abbastanza compatto, ma presuppone che non sia necessario eseguire alcuna conversione di tipo durante la lettura


2
Mmh ... Ho appena notato che volevi un formato specifico che non fosse esattamente simile a CSV. Presumevo che volessi lo stile CSV (cioè una riga per coppia chiave-valore) perché stavi utilizzando il modulo CSV ...
Ricardo Cárdenes

3
Oppure ... nel caso in cui l'approccio CSV sia esattamente quello che volevi, ma preferisci ":" come separatore, aggiungi semplicemente delimiter=':'quando crei lo scrittore e il lettore :)
Ricardo Cárdenes

2
Nota, dovresti chiudere il file tra scrittura e lettura. Guarda cosa è successo in questa domanda / risposta: stackoverflow.com/a/38467563/235698
Mark Tolonen

1
@ MarkTolonen sicuramente, withsarebbe meglio usarlo . Cambierò gli esempi per rispecchiarlo ...
Ricardo Cárdenes

1
@ DareYang scusa per il ritardo. In realtà, non sono sicuro del motivo per cui l'ho scritto allora. Non è necessario. Durante la scrittura, l'effetto di ciò è di lasciare i caratteri di nuova riga non tradotti (cioè, se scrivi \n, entrerai \nnel file). Se lasciato da solo, entra in gioco la "modalità universale" e le nuove righe vengono tradotte nell'impostazione predefinita per il sistema operativo corrente. Dato che non è molto utile qui (tranne se vuoi avere newline prevedibili), lo rimuoverò.
Ricardo Cárdenes

27

Solo per dare un'opzione, la scrittura di un dizionario in un file csv potrebbe essere eseguita anche con il pacchetto pandas. Con l'esempio fornito potrebbe essere qualcosa del genere:

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

La cosa principale da tenere in considerazione è impostare il parametro "orient" su "index" all'interno del metodo from_dict . Questo ti permette di scegliere se vuoi scrivere ogni chiave del dizionario in una nuova riga.

Inoltre, all'interno del metodo to_csv il parametro header è impostato su False solo per avere solo gli elementi del dizionario senza fastidiose righe. Puoi sempre impostare i nomi delle colonne e degli indici all'interno del metodo to_csv.

Il tuo output sarebbe simile a questo:

key1,a
key2,b
key3,c

Se invece vuoi che le chiavi siano i nomi delle colonne, usa semplicemente il parametro 'orient' predefinito che è 'colonne', come potresti controllare nei link della documentazione.


2
Eccellente ha funzionato come un fascino :). Il mio valore era un elenco e ha generato il mio CSV con tutti i valori dell'elenco in più celle e mappato alla chiave nella prima colonna.
vinsinraw

14

Il modo più semplice è ignorare il modulo csv e formattarlo da soli.

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

8
Se keyottieni una virgola, passerai un brutto momento.
Ali Ashraf

5
Lo trovo più semplice da usare csv.writer(...).writerows(my_dict.items()). Il csvmodulo fa molto di più che aggiungere virgole e nuove righe.
Martijn Pieters

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

1
Fornisci anche alcune informazioni o commenti sulla tua risposta.
NDM

2

Puoi semplicemente fare:

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

In modo che tu possa avere

chiave_1: valore_1, chiave_2: valore_2


3
Meglio sarebbe ','.join("%s:%s" % (k,v) for k,v in mydict.items()): di solito è meglio iterare sugli elementi di un dict, che ti fornisce chiavi e valori insieme, che sulle chiavi di un dict e fare ricerche di valore 'n'. ','.join(...)si occupa di inserire solo virgole tra i valori, senza aggiungere la virgola finale in più.
PaulMcG

nota che non avrai bisogno del punto e virgola alla fine per questo codice python
beep_check

1

Personalmente ho sempre trovato fastidioso il modulo csv. Mi aspetto che qualcun altro ti mostri come farlo in modo intelligente, ma la mia soluzione rapida e sporca è:

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

Tuttavia, se vuoi rileggerlo, dovrai eseguire un'analisi irritante, soprattutto se è tutto su una riga. Ecco un esempio che utilizza il formato di file proposto.

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

Vorrei andare con la risposta di Ricardo. O almeno usa linee separate.
Griffith Rees

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

inserisci qui la descrizione dell'immagine


Non credo sia necessario chiudere esplicitamente il file nell'ultima riga. Il gestore del contesto lo fa per te.
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

Sarebbe meglio se aggiungessi una piccola spiegazione
Roaim

-2

Hai provato ad aggiungere la "s" su: in w.writerow(mydict)questo modo w.writerows(mydict):? Questo problema è accaduto a me, ma con le liste stavo usando il singolare invece del plurale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.