2010-07-07 5 views
2

J'ai une structure de données qui ressemble à ceci:lecture/écriture d'une liste de dictionnaires imbriqués à/à partir d'un fichier CSV (Python)

data =[ 
{'key_1': { 'calc1': 42, 'calc2': 3.142 } }, 
{'key_2': { 'calc1': 123.4, 'calc2': 1.414 } }, 
{'key_3': { 'calc1': 2.718, 'calc2': 0.577 } } 
] 

Je veux être en mesure d'enregistrer/et charger les données dans un fichier CSV avec le format suivant

key, calc1, calc2 <- header 
key_1, 42,  3.142 <- data rows 
key_2, 123.4, 1.414 
key_3, 2.718, 0.577 

Quelle est la manière « Pythonic » pour lire/enregistrer cette structure de données vers/à partir d'un fichier CSV comme celle-ci?

+0

Sur intérêt, pourquoi voudriez-vous utiliser une liste de n dicts de dicts de longueur, au lieu d'une seule longueur de dictée? – naught101

Répondre

5

Je ne pense pas qu'il serait possible d'utiliser le module csv, en raison de toutes les particularités de vos besoins et la structure, mais vous pouvez le faire écrire assez facilement manuellement:

>>> with open('test.txt', 'w') as f: 
    f.write(','.join(['key', 'calc1', 'calc2']) + '\n') 
    f.writelines('{},{},{}'.format(k, *v.values()) + '\n' for l in data for k,v in l.items()) 
+0

@silentghost: +1 pour l'extrait sympa et court. Je suis sûr que ce que j'aurais trouvé, aurait été beaucoup plus verbeux. Cependant, avec la concision, vient un niveau de "wtf-ness". Pourriez-vous s'il vous plaît expliquer la troisième ligne - les paramètres étant passés à writelines()? Merci. – morpheous

+0

peut-être une note que cette mise en forme sorta ne fonctionne qu'avec les versions Python de 2.6 et suivantes – Tshepang

+0

c'est juste un itérateur de chaîne. Chaque format étant une liste séparée par des virgules, en raison de l'imbrication de vos 'data', j'ai dû répéter deux fois. – SilentGhost

6

Juste pour montrer une version qui n'utilise le module csv:

from csv import DictWriter 

data =[ 
{'key_1': { 'calc1': 42, 'calc2': 3.142 } }, 
{'key_2': { 'calc1': 123.4, 'calc2': 1.414 } }, 
{'key_3': { 'calc1': 2.718, 'calc2': 0.577 } } 
] 

with open('test.csv', 'wb') as f: 
    writer = DictWriter(f, ['key', 'calc1', 'calc2']) 
    writer.writerow(dict(zip(writer.fieldnames, writer.fieldnames))) # no automatic header :-(
    for i in data: 
     key, values = i.items()[0] # each dict in data contains only one entry 
     writer.writerow(dict(key=key, **values)) # first make a new dict merging the key and the values 
+0

Vous devriez pouvoir utiliser 'writer.writeheader()' pour écrire l'en-tête. (à partir de 2.7) :-) –

-1

Je me sens de loin la meilleure approche est de transformer le dictionnaire d'abord dans une trame de données de pandas géants et de là, très pratique dans un fichier csv.

import pandas as pd  
df = pd.DataFrame.from_dict(data, orient='index') # it is either ‘columns’ or ‘index’ (simple transpose) 
    df.to_csv('filepath/name.csv') 

Pour charger le fichier dans le formulaire dict

df.to_csv('filepath/name.csv') 
data_dict = df.to_dict() 

Pour les cas plus complexes ont un regard sur la documentation de pandas géants http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.from_dict.html et http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_dict.html

Questions connexes