2009-11-27 12 views
14

tengo cadenas que se parecen a éste:analizar una cadena que representa una lista de tuplas

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

y me gustaría convertir cada uno de ellos en una estructura de datos pitón. Preferiblemente una lista (o tupla) de tuplas que contiene un par de valores flotantes.

Podría hacerlo con eval("(8, 12.25), (13, 15), (16.75, 18.5)"), lo que me da una tupla de tuplas, pero no creo que la evaluación ingenua de información externa sea una decisión acertada.

Así que me pregunté cómo sería una elegante solución pitonica.

Respuesta

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, esto podría no ser robusta como para tener una sola tupla en la lista. ¿Qué pasaría si ingresases? "(8, 12.25)". Que obtendrías solo una tupla en lugar de una tupla en una tupla. Creo que obtendrías la tupla anidada deseada si la entrada fuera "(8, 12.25), "(tenga en cuenta la coma final). Pero no probé esto ya que no tengo instalado Python 2.6 en esta máquina. – Tom

+0

Buena captura Tom. Todavía no pensaba en eso y en realidad sería un problema en mi situación. Voy a verificar eso después del análisis. Gracias por el aviso. Desafortunadamente, el método no está disponible en python2.5 pero en mi caso está bien ya que lo estoy usando en un script de importación de datos de motor de aplicación y no en el motor de la aplicación. – tosh

+0

+1: No sabía 'ast.literal_eval' antes, ¡y es muy útil! –

1

Si está trabajando con un archivo CSV, y usted quiere más de la solución "ingenua", que no maneja ningún error, es probable que mejores resultados con el Python's CSV module.

+0

Lo siento, definí la pregunta un poco vaga. La cadena es en realidad un valor que obtengo como uno de los valores separados por coma/punto y coma. Eliminaré el bit CSV de la pregunta, ya que podría ser confuso. Estoy usando el módulo CSV por cierto. Eso es genial. Gracias por responder sin embargo. – tosh

1

Descargar PyParsing.

He trabajado con él antes. Puede obtener un comportamiento de análisis bastante robusto, y creo que proporciona componentes integrados que manejarán todas sus necesidades de análisis con este tipo de cosas. Busque commaSeparatedList y 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 

esto debería hacer el trabajo.

2

He usado safe_eval para trabajos como este en el pasado.

1

¿Qué hay de malo en hacerlo sistemáticamente? dividir en ")", y luego ir a través de la lista, eliminar todo "(".

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

Ahora se puede llevar a cada elemento en su estructura de datos.

Cuestiones relacionadas