2010-01-20 15 views
19

Desidero ordinare una tabella CSV per data. Iniziato essere un compito semplice:ordina csv per colonna

import sys 
import csv 

reader = csv.reader(open("files.csv"), delimiter=";") 

for id, path, title, date, author, platform, type, port in reader: 
    print date 

Ho usato il modulo CSV di Python per leggere in un file con quella struttura:

id;file;description;date;author;platform;type;port 
  • La data ha la certificazione ISO-8601, quindi posso ordinare abbastanza facilmente senza analisi: 2003-04-22 e. g.
  • Desidero ordinare la data, le voci più recenti prima
  • Come si ottiene questo lettore in una struttura dati ordinabile? Penso che con qualche sforzo potrei creare un datalist: datelist + = date, split e sort. Tuttavia devo ri-identificare la voce completa nella tabella CSV. Non si tratta solo di ordinare una lista di cose.
  • csv non sembra avere un costruito in funzione di ordinamento

La soluzione ottimale sarebbe quella di avere un client CSV che gestisce il file come un database. Non ho trovato nulla di simile.

Spero che qualcuno conosce qualche bella magia di smistamento qui;)

Grazie,

Marius

+2

Se si desidera semplicemente uno strumento per ordinare i file CSV, vedere il mio progetto FOSS csvfix all'indirizzo http://code.google.com/p/csvfix/ –

risposta

47
import operator 
sortedlist = sorted(reader, key=operator.itemgetter(3), reverse=True) 

o l'uso lambda

sortedlist = sorted(reader, key=lambda row: row[3], reverse=True) 
+0

Questo riscrive il file o semplicemente salva l'elenco ordinato in la variabile? – Jeff

+1

@Jeff: non tocca il file originale. Se si desidera scrivere i risultati, è necessario farlo come operazione separata. –

+0

@ IgnacioVazquez-Abrams Qual è la differenza tra questi due metodi, cosa stanno facendo? Quale si dovrebbe scegliere? – abaumg

11

Il lettore si comporta come un generatore. Su un file con alcuni dati falsi:

>>> import sys, csv 
>>> data = csv.reader(open('data.csv'),delimiter=';') 
>>> data 
<_csv.reader object at 0x1004a11a0> 
>>> data.next() 
['a', ' b', ' c'] 
>>> data.next() 
['x', ' y', ' z'] 
>>> data.next() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

Utilizzando operator.itemgetter come Ignacio suggerisce:

>>> data = csv.reader(open('data.csv'),delimiter=';') 
>>> import operator 
>>> sortedlist = sorted(data, key=operator.itemgetter(2), reverse=True) 
>>> sortedlist 
[['x', ' y', ' z'], ['a', ' b', ' c']] 
2

in caso di più colonne di ordinamento:

with open('xxx.csv',newline='') as csvfile: 
    spamreader = csv.DictReader(csvfile, delimiter=";") 
    sortedlist = sorted(spamreader, key=lambda row:(row['title'],row['date']), reverse=False) 

Sarebbe prima di smistamento per title, quindi ordinare per date.