2010-07-08 12 views
9

ho scritto una funzione che serializza un elenco di dizionari come file CSV utilizzando il modulo csv, con codice come questo:Utilizzando DictWriter per scrivere un sottoinsieme di chiavi di un dizionario

data = csv.DictWriter(out_f, fieldnames) 
data.writerows(dictrows) 

Tuttavia, a volte mi voglio scrivi su un file solo un sottoinsieme delle chiavi di ogni dizionario. Se mi passa come fieldnames un sottoinsieme delle chiavi che ogni dizionario ha, ottengo l'errore:

"dict contains fields not in fieldnames" 

Come posso fare in modo che DictRows scriveranno solo un sottoinsieme dei campi a specificare in formato CSV, ignorando quelli campi che sono nel dizionario ma non nei nomi di campo?

risposta

33

più semplice e diretto approccio è quello di passare extrasaction='ignore' quando si inizializza l'istanza DictWriter, come documentato here:

If the dictionary passed to the writerow() method contains a key not found in fieldnames, the optional extrasaction parameter indicates what action to take. If it is set to 'raise' a ValueError is raised. If it is set to 'ignore' , extra values in the dictionary are ignored.

Funziona anche su writerows, che, al suo interno, proprio chiama writerow ripetutamente.

+1

L'opzione restval per chiave del dizionario non trovata è particolarmente utile insieme a extrasaction = 'ignore'. – Gregor

1

modifiche al codice:

dimenticare DictWriter, utilizzano scrittore ordinaria.

Poi anello sopra la vostra lista di dicts:

for d in dictrows: 
    ordinary_writer.writerow([d[fieldname] for fieldname in fieldnames]) 

Uso d.get(fieldname, "") invece di d[fieldname] se non si vuole un'eccezione se non v'è alcuna voce in d per un fieldname.

Nota per downvoters anonimi: questo sta facendo ciò che la soluzione di Alex sta facendo sotto la cappa (vedi Lib/csv.py) e lo fa un po 'meglio ... csv.py chiama una funzione per ottenere ogni riga in una lista e il coraggio di tale funzione è

return [rowdict.get(key, self.restval) for key in self.fieldnames] 
+0

-1; nessun motivo per farlo quando 'DictWriter' fornisce un parametro conveniente per risolvere il problema automaticamente, come descritto nella risposta di Alex. –

Problemi correlati