2009-11-27 2 views
14

repräsentiert habe ich Strings, die wie dieses aussehen:einen String parsen, die eine Liste von Tupeln

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

und ich möchte jeden von ihnen in eine Python-Datenstruktur konvertieren. Vorzugsweise eine Liste (oder Tupel) von Tupeln, die ein Paar von Float-Werten enthalten.

Ich könnte das mit eval("(8, 12.25), (13, 15), (16.75, 18.5)") tun, die mir ein Tupel-Tupel gibt, aber ich denke nicht, naiv externen Informationen zu bewerten wäre eine kluge Entscheidung.

Also fragte ich mich, wie eine elegante pythonische Lösung aussehen könnte.

Antwort

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, nicht robust sein könnte, eine einzige mit Tupel in der Liste. Was wäre, wenn Sie "(8, 12.25)" eingegeben hätten. Dass Sie nur ein Tupel anstelle eines Tupels in einem Tupel erhalten würden. Ich glaube, dass Sie das gewünschte verschachtelte Tupel bekommen würden, wenn die Eingabe "(8, 12.25), "(beachte das nachgestellte Komma). Aber ich habe das nicht getestet, da ich auf diesem Rechner kein Python 2.6 installiert habe. – Tom

+0

Guter Fang Tom. Ich habe noch nicht darüber nachgedacht und es wäre tatsächlich ein Problem in Ich werde das nach dem Parsing überprüfen, danke für's heads up. Leider die Methode ist in python2.5 nicht verfügbar, aber in meinem Fall ist das ok, da ich es in einem App-Engine-Datenimport-Skript verwende und nicht in der App-Engine selbst. – tosh

+0

+1: Ich kannte "ast.literal_eval" vorher nicht - und es ist so praktisch! –

1

Wenn Sie mit einer CSV-Datei arbeiten, und Sie wollen mehr als die „naive“ Lösung, die keine Fehler behandeln, sind Sie wahrscheinlich am besten aus den Python's CSV module verwenden.

+0

Entschuldigung, ich habe die Frage ein wenig vage definiert. Die Zeichenfolge ist eigentlich ein Wert, den ich als eine der durch Komma/Semikolon getrennten Werte erhalte. Ich werde das CSV-Bit aus der Frage entfernen, da es möglicherweise verwirrend ist. Ich benutze übrigens das CSV-Modul. Es ist großartig. Danke für die Antwort. – tosh

1

Download PyParsing.

Ich habe damit schon einmal gearbeitet. Sie können ein ziemlich robustes Parsing-Verhalten daraus ziehen, und ich denke, dass es Builtins zur Verfügung stellt, die Ihre gesamten Parsing-Anforderungen mit dieser Art von Dingen bewältigen. Suchen Sie nach commaSeparatedList und 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 

Dies sollte die Aufgabe erledigen.

2

Ich habe safe_eval für solche Jobs in der Vergangenheit verwendet.

1

Was ist daran falsch, es systematisch zu tun? aufgeteilt auf „)“, dann durch die Liste gehen, entfernen Sie alle „(“.

>>> 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'] 
[''] 

Jetzt können Sie jedes Element in der Datenstruktur bringen.