2009-11-27 12 views
14

Ho stringhe che assomigliano a questo:parsing di una stringa che rappresenta una lista di tuple

"(8, 12.25), (13, 15), (16.75, 18.5)" 

e vorrei convertire ognuno di loro in una struttura dati pitone. Preferibilmente una lista (o tupla) di tuple contenenti una coppia di valori float.

Potrei farlo con eval("(8, 12.25), (13, 15), (16.75, 18.5)") che mi dà una tupla di tuple, ma non penso che la valutazione ingenua di informazioni esterne sarebbe una decisione saggia.

Quindi mi chiedevo come fosse un'elegante soluzione pitonica.

risposta

21
>>> import ast 
>>> print ast.literal_eval("(8, 12.25), (13, 15), (16.75, 18.5)") 
((8, 12.25), (13, 15), (16.75, 18.5)) 
+1

jfyi, questo potrebbe non essere robusto per avere un unico tuple nella lista: cosa succederebbe se tu inserissi "(8, 12.25)" .Questi otterresti solo una tupla invece di una tupla in una tupla Credo che otterresti la tupla annidata desiderata se l'input fosse "(8, 12.25), "(nota la virgola finale), ma non ho provato questo perché non ho installato python 2.6 su questa macchina – Tom

+0

Buona cattura Tom. Non ci avevo ancora pensato e sarebbe stato effettivamente un problema in la mia situazione, lo controllerò dopo averlo analizzato. Grazie per l'avviso, purtroppo il metodo non è disponibile in python2.5 ma nel mio caso va bene così come lo sto usando in uno script di importazione dei dati del motore di app e non nel motore stesso dell'app. – tosh

+0

+1: non conoscevo 'ast.literal_eval' prima - ed è così comodo! –

1

se si sta lavorando con un file CSV, e si desidera più che la soluzione "ingenuo", che non gestisce eventuali errori, si è probabilmente meglio fuori usando il Python's CSV module.

+0

Mi dispiace, ho definito la domanda un po 'vaga. La stringa è in realtà un valore che ottengo come uno dei valori separati da virgola/punto e virgola. Rimuoverò il bit CSV dalla domanda in quanto potrebbe creare confusione. A proposito, sto usando il modulo CSV. È grande. Grazie per aver risposto. – tosh

1

Download PyParsing.

Ho già lavorato con esso. Si può ottenere un comportamento di parsing piuttosto robusto, e penso che fornisca builtins che gestiranno le vostre esigenze di analisi con questo tipo di cose. Cerca virgola SeparataLista e nestedExpr.

3
def parse(s): 
    tuples = s.split('), ') 
    out = [] 
    for x in tuples: 
     a,b = x.strip('()').split(', ') 
     out.append((float(a),float(b))) 
    return out 

questo dovrebbe fare il lavoro.

2

Ho usato safe_eval per lavori come questo in passato.

1

cosa c'è di sbagliato nel farlo sistematicamente? Split On ")", quindi scorrere l'elenco, rimuovere tutti "(".

>>> s="(8, 12.25), (13, 15), (16.75, 18.5)" 
>>> [ i.replace("(","") for i in s.split(")") ] 
['8, 12.25', ', 13, 15', ', 16.75, 18.5', ''] 
>>> b = [ i.replace("(","") for i in s.split(")") ] 
>>> for i in b: 
... print i.strip(", ").replace(" ","").split(",") 
... 
['8', '12.25'] 
['13', '15'] 
['16.75', '18.5'] 
[''] 

Ora è possibile portare ogni elemento nella vostra struttura di dati.

Problemi correlati