2015-06-23 7 views
6

Ich habe eine Liste von Tausenden von Elementen einer Form wie folgt aus:Wie kann ich eine Liste von Strings als Liste von Tupeln in Python auswerten?

pixels = ['(112, 37, 137, 255)', '(129, 39, 145, 255)', '(125, 036, 138, 255)' ...] 

Ich versuche, diese Zeichenfolge Elemente Tupel zu konvertieren ast.literal_eval verwenden, aber es bricht auf Dinge wie führende Nullen zu begegnen (zB in der dritte gezeigte Tupelstring) mit dem Fehler SyntaxError: invalid token.

pixels = [ast.literal_eval(pixel) for pixel in pixels] 

Was wäre ein guter Weg, um mit Dingen wie diese zu behandeln und diese Liste von Strings als eine Liste von Tupeln ausgewertet werden?

+0

@BhargavRao Oktanzahl in Python 3 unterstützt das 0xx-Format nicht. –

+0

@BhargavRao Hallo, dort. Der spezifische Fehler ist '' 'SyntaxError: ungültiges Token'''. Ich habe das gerade zu der Frage hinzugefügt. – d3pd

+2

@BhargavRao Eine führende '0' in Python 2.x war ein oktales Literal. In Python 3.x ist dies nicht mehr erlaubt. Zum Beispiel ist "055" oktal für den Dezimalwert "45". – CoryKramer

Antwort

4

Verwenden Sie das Modul re.

>>> import re 
>>> import ast 
>>> pixels = ['(112, 37, 137, 255)', '(129, 39, 145, 255)', '(125, 036, 138, 255)'] 
>>> [ast.literal_eval(re.sub(r'\b0+', '', pixel)) for pixel in pixels] 
[(112, 37, 137, 255), (129, 39, 145, 255), (125, 36, 138, 255)] 

re.sub(r'\b0+', '', pixel) hilft, die führenden Nullen zu entfernen. \b passt zwischen einem Wort Zeichen und einem Nicht-Wort-Zeichen oder umgekehrt, so dass hier eine Wortgrenze existiert vor 0 und nach dem Leerzeichen oder ( Symbol.

Update:

>>> pixels = ['(0, 0, 0, 255)', '(129, 39, 145, 255)', '(125, 036, 138, 255)'] 
>>> [ast.literal_eval(re.sub(r'\b0+\B', '', pixel)) for pixel in pixels] 
[(0, 0, 0, 255), (129, 39, 145, 255), (125, 36, 138, 255)] 
+0

Vielen Dank für Ihre Hilfe zu diesem Thema. Ihre Lösung ist sehr nahe, aber es bricht Null Elemente von Tupeln, zum Beispiel, '' '(0, 0, 0, 255)' '' wird ausgewertet zu '' '(,,, 255)' ''. Würdest du zufällig einen Weg finden? – d3pd

+0

Goood fangen, versuchen '[ast.literal_eval (re (r '\ b0 + \ B', '', Pixel)) für Pixel in Pixel]' –

+0

Eine alternative Regex-Ansatz: '[Tupel (Int (d) für d in re.findall ('\ d +', Pixel)) für Pixel in Pixel] '. (Nicht so gut wie geschriebene Antwort.) –

4

Keine Notwendigkeit ast.literal_eval oder re zu verwenden. Streichen Sie einfach die Klammern und erzwingen Sie sie zu ganzen Zahlen:

+0

Vielen Dank für Ihre Lösung. Es ist auch ein guter Ansatz. – d3pd