2011-07-20 7 views
1

J'ai un énorme gâchis d'une liste imbriquée qui ressemble à quelque chose comme ça, juste plus:liste imbriquée nettoyage

fruit_mess = [['watermelon,0,1.0\n'], ['apple,0,1.0\n'], ['"pineapple",0,1.0\n'], ['"strawberry, banana",0,1.0\n'], ['peach plum pear,0,1.0\n'], ['"orange, grape",0,1.0\n']] 

En fin de compte, je veux quelque chose qui ressemble à ceci:

neat_fruit = [['watermelon',0,1.0], ['apple',0,1.0], ['pineapple',0,1.0], ['strawberry, banana',0,1.0], ['peach plum pear',0,1.0], ['orange, grape',0,1.0]] 

mais je Je ne sais pas comment gérer les guillemets dans les citations et comment séparer les fruits des nombres, surtout avec les virgules qui séparent certains des fruits. J'ai essayé beaucoup de choses, mais tout semble en faire encore plus. Toutes les suggestions seraient grandement appréciées.

Répondre

6

Utilisez le module csv (dans la bibliothèque standard) pour gérer les fruits à double cité par des virgules dans leur nom:

import csv 
import io 

fruit_mess = [['watermelon,0,1.0\n'], ['apple,0,1.0\n'], ['"pineapple",0,1.0\n'], ['"strawberry, banana",0,1.0\n'], ['peach plum pear,0,1.0\n'], ['"orange, grape",0,1.0\n']] 

# flatten the list of lists into a string: 
data='\n'.join(item[0].strip() for item in fruit_mess)  
reader=csv.reader(io.BytesIO(data)) 
neat_fruit=[[fruit,int(num1),float(num2)] for fruit,num1,num2 in reader] 

print(neat_fruit)  
# [['watermelon', 0, 1.0], ['apple', 0, 1.0], ['pineapple', 0, 1.0], ['strawberry, banana', 0, 1.0], ['peach plum pear', 0, 1.0], ['orange, grape', 0, 1.0]] 
+1

Clever. Je me demande si c'était un fichier csv miss miss en premier lieu. – Wilduck

+0

cela semble très bien, mais malheureusement j'ai python 2.5 qui n'a pas le module io – user808545

+1

@ user808545: Dans ce cas, utilisez 'cStringIO.StringIO' à la place de' io.BytesIO'. – unutbu

0

Une solution basée sur les expressions régulières:

>>> import re 
>>> regex = re.compile(r'("[^"]*"|[^,]*),(\d+),([\d.]+)') 
>>> neat_fruit = [] 
>>> for item in fruit_mess: 
...  match = regex.match(item[0]) 
...  result = [match.group(1).strip('"'), int(match.group(2)), float(match.group(3))] 
...  neat_fruit.append(result) 
... 
>>> neat_fruit 
[['watermelon', 0, 1.0], ['apple', 0, 1.0], ['pineapple', 0, 1.0], ['strawberry, 
banana', 0, 1.0], ['peach plum pear', 0, 1.0], ['orange, grape', 0, 1.0]] 
+0

hmmm pour une raison quelconque cela me donne result = [match.group (1) .strip ('"'), int (match.group (2)), float (match.group (3))] AttributeError: 'NoneType 'objet n'a pas d'attribut' groupe ', je ne sais pas ce que je fais mal – user808545

+0

Cela signifie probablement que la correspondance a échoué sur l'une des chaînes.La regex fonctionne sur les données d'échantillon dans votre question, mais s'il y a d'autres formats dans votre données réelles, l'expression régulière pourrait échouer. –

1

Un de plus simple solution:

fruit_mess = [['watermelon,0,1.0\n'], ['apple,0,1.0\n'], ['"pineapple",0,1.0\n'], ['"strawberry, banana",0,1.0\n'], ['peach plum pear,0,1.0\n'], ['"orange, grape",0,1.0\n']] 
for i,x in enumerate(fruit_mess): 
    data = x[0].rstrip('\n').rsplit(',', 2) 
    fruit_mess[i] = [data[0], int(data[1]), float(data[2])]