2014-12-10 24 views
6

Il codice che ho finora è in una funzione che legge fondamentalmente un file CSV e stampe il suo contenuto:Conversione il contenuto di un file CSV in un dizionario

def read(filename): 
    with open(filename, 'r') as csvfile: 
     reader = csv.reader(csvfile, delimiter=',') 
     for row in reader: 
      print(row) 

Contenuti di sailor.csv:

name, mean performance , std dev 
Alice, 100, 0, 
Bob, 100, 5, 
Clare, 100, 10, 
Dennis, 90, 0, 
Eva, 90, 5, 

read('sailor.csv') e l'esecuzione della funzione

uscita corrente:

['name', ' mean performance ', ' std dev'] 
['Alice', ' 100', ' 0', ''] 
['Bob', ' 100', ' 5', ''] 
['Clare', ' 100', ' 10', ''] 
['Dennis', ' 90', ' 0', ''] 
['Eva', ' 90', ' 5', ''] 

uscita richiesta:

{'Dennis': (90.0, 0.0), 'Clare':(100.0, 10.0), 
'Eva': (90.0, 5.0), 'Bob': (100.0, 5.0), 'Alice': (100.0, 0.0)} 

tutte le idee come posso ottenere che la produzione? Usando Python 3.4.2 se questo ti aiuta, la spiegazione della tua risposta sarà apprezzata!

risposta

2

Credo che questo sia ciò che si vuole:

import csv 

def read(filename): 
    out_dict = {} 
    with open(filename, 'r') as csvfile: 
     reader = csv.reader(csvfile, delimiter=',') 
     next(csvfile) # skip the first row 
     for row in reader: 
      out_dict[row[0]] = float(row[1]), float(row[2]) 
      print(row) 

    return out_dict 

print(read('data.csv')) 

Stampe:

{'Bob': (' 100', ' 5'), 'Clare': (' 100', ' 10'), 'Alice': (' 100', ' 0'), 'Dennis': (' 90', ' 0'), 'Eva': (' 90', ' 5')} 

Non c'è molto da spiegare qui. Basta inserire i valori nel dizionario e saltare la prima riga aggiunta. Ho assunto che i nomi delle persone siano unici.

+0

Il suo output richiesto ha numeri in virgola mobile; o forse è solo ".0" aggiunto. E non ci sono virgolette attorno ai numeri. – Marichyasana

+0

L'ho ottimizzato leggermente, aggiungendo il float prima della riga [1] e la riga [2] hanno corretto i numeri .. ora funziona perfettamente! Grazie!- Non c'è bisogno di usare la stampa perché chiamerò la funzione più tardi .. read ('sailor.csv') funziona per me! – Alex

+0

@Alex FYI, se fai un suggerimento di modifica, dovresti fornire una descrizione più dettagliata su * perché * hai fatto la modifica (piuttosto che * cosa * hai modificato) ... Non riesci a vedere i commenti nel Revisione di modifiche consigliate; solo il post con le modifiche e il motivo che fornisci; [vedi questo meta post] (http://meta.stackoverflow.com/questions/278894/more-context-in-the-suggested-edits-review) ... Non dovresti cambiare la tua domanda per includere l'accettato risposta; fai clic su "Accetto" su una domanda per farlo, questo mantiene la domanda "pulita" per le persone future con un problema simile che finiscono qui. – Carpetsmoker

8

utilizzando la libreria standard csv e la comprensione dizionario ...

import csv 
with open('sailor.csv') as csvfile: 
    reader = csv.reader(csvfile) 
    next(reader) 
    d = {r[0] : tuple(r[1:-1]) for r in reader} 

Dove d sarà il dizionario che si desidera. d[1:-1] divide la matrice dal secondo al penultimo elemento.

EDIT: salta le intestazioni, converte in tuple

+0

E la prima fila: '[ 'name', 'significare prestazioni', ' std dev '] '? – Marcin

+0

Questo è vicino, ma i numeri dovrebbero essere in tuple, penso? così: "Eva": (90.0, 5.0) non "Eva": [90.0, 5.0]. E 'name': ['mean performance'] è anche stampato – Alex

0

Uso DictReader:

def read(filename): 
    with open(filename, 'r') as csvfile: 
     reader = csv.DictReader(csvfile, delimiter=',') 
     for row in reader: 
      print(row) 
+1

nessuna riga sarà '{" header1 ": val1," header2 ": val2, ...}' invece della tupla/lista come mostrato sopra? –

+0

sei corretto. ho letto male la domanda Grazie! – Andrew

2

Allora ... So che questa domanda è stata in gran parte risposto, ma ho pensato solo buttare una battuta nel mix di aggiungere alle risposte accorciamento:

from csv import reader 
from itertools import islice 

{r[0] : tuple(r[1:-1]) for r in islice(reader(open('sailor.csv')), 1, None)} 

l'unica fatto romanzo aggiunge islice per saltare la riga di intestazione in modo pulito.

+0

una cosa che ti è mancato sta facendo galleggiare i numeri, oltre che bello :) – Alex

0

Ecco la mia soluzione se mi è consentito:

>>> import pyexcel as pe 
>>> s = pe.load("sailor.csv", name_rows_by_column=0, name_columns_by_row=0) 
>>> s.format(float) 
>>> s 
Sheet Name: csv 
+--------+------------------+---------+---+ 
|  | mean performance | std dev | | 
+========+==================+=========+===+ 
| Alice | 100    | 0  | 0 | 
+--------+------------------+---------+---+ 
| Bob | 100    | 5  | 0 | 
+--------+------------------+---------+---+ 
| Clare | 100    | 10  | 0 | 
+--------+------------------+---------+---+ 
| Dennis | 90    | 0  | 0 | 
+--------+------------------+---------+---+ 
| Eva | 90    | 5  | 0 | 
+--------+------------------+---------+---+ 
>>> del s.column[''] # delete the column which has '' as its name 
>>> s.to_dict(True) # make a dictionary using row names as key 
OrderedDict([('Alice', [100.0, 0.0]), ('Bob', [100.0, 5.0]), 
('Clare', [100.0, 10.0]), ('Dennis', [90.0, 0.0]), ('Eva', [90.0, 5.0])]) 

Ecco la documentazione relativa pe.load e to_dict di pyexcel

Problemi correlati