2015-06-23 22 views
6

Ho una lista di migliaia di elementi di un modulo come il seguente:Come posso valutare un elenco di stringhe come un elenco di tuple in Python?

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

Sto cercando di convertire questi elementi stringa di tuple utilizzando ast.literal_eval, ma è rottura su incontrando cose come zeri iniziali (ad esempio in la terza stringa di tupla mostrata) con l'errore SyntaxError: invalid token.

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

Quale sarebbe un buon modo per affrontare le cose in questo modo e ottenere questo elenco di stringhe valutato come una lista di tuple?

+0

@BhargavRao I numeri ottali in Python 3 non supportano il formato 0xx. –

+0

@BhargavRao Ciao. L'errore specifico è "" SyntaxError: invalid token'''. L'ho appena aggiunto alla domanda. – d3pd

+2

@BhargavRao Uno '0' leader in Python 2.x era un valore letterale ottale. In Python 3.x questo non è più permesso. Ad esempio, '055' è ottale per il valore decimale' 45'. – CoryKramer

risposta

4

Utilizzare il modulo 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) aiuta a rimuovere gli zeri iniziali. \b corrispondenze tra un carattere di parola e un carattere di non parola o viceversa, quindi qui deve esserci un confine di parola esistente prima di zero e dopo lo spazio o il simbolo (.

Aggiornamento:

>>> 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

Grazie mille per il vostro aiuto in merito. La tua soluzione è molto vicina, ma sta rompendo zero elementi di tuple, per esempio, '' '(0, 0, 0, 255)' '' viene valutato in '' '(,,, 255)' ''. Ti piacerebbe sapere un modo per aggirare questo? – d3pd

+0

Goood catch, prova '[ast.literal_eval (re.sub (r '\ b0 + \ B', '' pixel)) per pixel in pixel]' –

+0

Un approccio regex alternativo: '[tupla (int (d) per d in re.findall ('\ d +', pixel)) per pixel in pixel] '. (Non buono come risposta postata.) –

4

Non c'è bisogno di usare ast.literal_eval o re. Basta togliere le parentesi e forzare i numeri interi:

def tupleize(s): 
    s = s.strip('()').split(',') 
    return tuple(int(entry) for entry in s) 

pixels = [tupleize(pixel) for pixel in pixels] 
+0

Grazie mille per la soluzione. È anche un buon approccio. – d3pd

Problemi correlati