2011-10-26 4 views
3

Je traite un fichier CSV similaire à celuiComment analyser un fichier CSV mixte en Python?

foo; val1; position1 
bar; name1; address1; phone_nbr1 
bar; name2; address2; phone_nbr2 
foo; val2; position2 
bar; name3; address3; phone_nbr3 
bar; name4; address4; phone_nbr4 
bar; name5; address5; phone_nbr5 
bar; name6; address6; phone_nbr6 
foo; val3; position3 

Inutile de dire que je ne peux pas modifier le CSV.

Les instances affichées dans foo lignes sont différentes de celles avec bar lignes (avis ils ont même pas le même nombre de champs)

J'ai besoin simplement lire ces données, pas besoin de l'écrire.

Ma première idée était de séparer le fichier en deux fichiers temporaires, puis de les lire séparément avec un csv.DictReader, mais je n'aime vraiment pas cette approche.

Existe-t-il une façon plus simple de faire cela? Je voudrais éviter si possible d'écrire des fichiers sur le disque. Pour l'anecdote, j'utilise Python2.7 sur une machine Solaris 10.

Répondre

6

Vous pouvez récupérer les enregistrements d'une csv.reader dans deux listes différentes, en fonction de leur longueur (ou tout autre critère que vous utilisez pour distinguer les deux cours d'eau):

list1 = [] 
list2 = [] 
with open("input.csv", "rb") as f: 
    for record in csv.reader(f, delimiter=";"): 
     if len(record) == 3: 
      list1.append(record) 
     else: 
      list2.append(record) 
1

Qu'en est-il juste en utilisant str.split sur chaque ligne?

items = line.split(";") 

Ensuite, si le premier élément de la liste est itemsfoo vous faites une chose, et si elle est bar que vous faites autre chose.

3

csv.reader() n'a pas de problème avec ceci:

import csv 
foo = [] 
bar = [] 
with open("test.csv", 'r') as f: 
    c = csv.reader(f, delimiter = ";") 
    for row in c: 
     if row[0] == "foo": 
      foo.append(row[1:]) 
     elif row[0] == "bar": 
      bar.append(row[1:]) 
print(a) 
print(b) 

résultats dans

[[' val1', ' position1'], [' val2', ' position2'], [' val3', ' position3']] 
[[' name1', ' address1', ' phone_nbr1'], [' name2', ' address2', ' phone_nbr2'], [' name3', ' address3', ' phone_nbr3'], [' name4', ' address4', ' phone_nbr4'], [' name5', ' address5', ' phone_nbr5'], [' name6', ' address6', ' phone_nbr6']] 
0

Le fait que les lignes soient différentes n'est pas un problème pour le module csv, mais vous devrez analyser le contenu de la ligne différemment selon la première 'cellule'.

Exemple de code:

with open(input_file, 'rb') as fin: 
    c = csv.reader(fin) 
    for line in c: 
     if line[0] == 'foo': 
       # do some treatment 
     elif line[0] == 'bar': 
       # do something else 
    c.close() 
0

On ne sait pas de votre question ce que vous voulez vraiment atteindre, mais je ne suis pas sûr que vous avez besoin du module csv ici.

for row in myfile.readlines(): 
    cols = [r.strip() for r in row.split(';')] 
    if (cols[0] == "foo"): 
     # Do something for foo 
    elif (cols[0] == "bar"): 
     # Do something for bar 
0

Qu'en est-il quelque chose comme:

foos = [] 
bars = [] 
for line in csv.reader(open("file.csv","rb"), delimiter=";"): 
    if line[0] == "foo": 
    foos.append(Foo(line[1], line[2])) 
    else: 
    bars.append(Bar(line[1], line[2], line[3])) 

En supposant que vous avez un Foo et une classe Bar prenant le reste de vos cellules en ligne comme arguments.

Questions connexes