2010-01-20 5 views
19

Je veux trier une table CSV par date. A commencé d'être une tâche simple:trier csv par colonne

import sys 
import csv 

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

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

je module CSV Python pour lire dans un fichier avec cette structure:

id;file;description;date;author;platform;type;port 
  • La date est certifiée ISO 8601, donc je peux trier assez facilement sans analyser: 2003-04-22 e. g.
  • Je veux trier par date, plus récents entrées en premier
  • Comment obtenir ce lecteur dans une structure de données triable? Je pense qu'avec un peu d'effort, je pourrais faire une liste de données: datelist + = date, split et tri. Cependant, je dois ré-identifier l'entrée complète dans la table CSV. Ce n'est pas juste de trier une liste de choses.
  • csv ne semble pas avoir un construit en fonction de tri

La solution optimale serait d'avoir un client CSV qui gère le fichier comme une base de données. Je n'ai rien trouvé de tel.

J'espère que quelqu'un connaît une belle magie de tri ici;)

Merci,

Marius

+2

Si vous voulez simplement un outil pour trier les fichiers CSV, voir mon projet FOSS csvfix à l'adresse http://code.google.com/p/csvfix/ –

Répondre

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

ou de l'utilisation lambda

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

Est-ce que cela réécrit le fichier, ou simplement sauvegarder la liste triée dans la variable? – Jeff

+1

@Jeff: Il ne touche pas le fichier d'origine. Si vous voulez écrire les résultats, vous devez le faire en tant qu'opération séparée. –

+0

@ IgnacioVazquez-Abrams Quelle est la différence entre ces deux méthodes, que font-ils? Lequel choisir? – abaumg

11

Les actes de lecteur comme un générateur. Sur un fichier avec des données faux:

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

En utilisant operator.itemgetter comme Ignacio suggère:

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

en cas de plusieurs colonnes de tri:

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

Il faudrait d'abord le tri par title, puis en triant par date.