Convertir la representación de cadena de la lista a la lista

Me preguntaba cuál es la forma más sencilla de convertir una lista de string como la siguiente en una list :

 x = u'[ "A","B","C" , " D"]' 

Incluso en caso de que el usuario coloque espacios entre las comas y espacios dentro de las comillas. Necesito manejar eso también para:

 x = ["A", "B", "C", "D"] 

en python.

Sé que puedo eliminar espacios con strip() y split() utilizando el operador dividido y verificar que no haya alfabetos. Pero el código se estaba volviendo muy torpe. ¿Hay una función rápida que no conozco?

 >>> import ast >>> x = u'[ "A","B","C" , " D"]' >>> x = ast.literal_eval(x) >>> x ['A', 'B', 'C', ' D'] >>> x = [n.strip() for n in x] >>> x ['A', 'B', 'C', 'D'] 

ast.literal_eval

Con ast.literal_eval, puede evaluar con seguridad un nodo de expresión o una cadena que contenga una expresión de Python. La cadena o el nodo proporcionado solo puede consistir en las siguientes estructuras literales de Python: cadenas, números, tuplas, listas, dados, booleanos y ninguno.

La eval es peligrosa: no debe ejecutar la entrada del usuario.

Si tiene 2.6 o más reciente, use ast en lugar de eval:

 >>> import ast >>> ast.literal_eval('["A","B" ,"C" ," D"]') ["A", "B", "C", " D"] 

Una vez que tengas eso, strip las cuerdas.

Si estás en una versión anterior de Python, puedes acercarte mucho a lo que quieres con una simple expresión regular:

 >>> x='[ "A", " B", "C","D "]' >>> re.findall(r'"\s*([^"]*?)\s*"', x) ['A', 'B', 'C', 'D'] 

Esto no es tan bueno como la solución ast, por ejemplo, no maneja correctamente las comillas escapadas en las cadenas. Pero es simple, no implica una evaluación peligrosa, y podría ser lo suficientemente bueno para tu propósito si estás en un Python antiguo sin ast.

El módulo json es una mejor solución siempre que exista una lista de diccionarios ordenada . La función json.loads(your_data) se puede usar para convertirla en una lista.

 >>> import json >>> x = u'[ "A","B","C" , " D"]' >>> json.loads(x) [u'A', u'B', u'C', u' D'] 

similar

 >>> x = u'[ "A","B","C" , {"D":"E"}]' >>> json.loads(x) [u'A', u'B', u'C', {u'D': u'E'}] 
 import ast l = ast.literal_eval('[ "A","B","C" , " D"]') l = [i.strip() for i in l] 

Suponiendo que todas sus entradas son listas y que las comillas dobles en la entrada realmente no importan, esto se puede hacer con un simple reemplazo de expresiones regulares. Es un poco perl-y, pero funciona como un encanto. Tenga en cuenta también que la salida ahora es una lista de cadenas de Unicode, no especificó que necesitaba eso, pero parece tener sentido dada la entrada de Unicode.

 import re x = u'[ "A","B","C" , " D"]' junkers = re.compile('[[" \]]') result = junkers.sub('', x).split(',') print result ---> [u'A', u'B', u'C', u'D'] 

La variable junkers contiene una expresión regular comstackda (para velocidad) de todos los caracteres que no deseamos, usando] como un carácter que requiere algunos trucos de barra invertida. Re.sub reemplaza todos estos caracteres por nada, y dividimos la cadena resultante en las comas.

Tenga en cuenta que esto también elimina espacios de las entradas internas u ‘[“oh no”]’ —> [u’ohno ‘]. Si esto no es lo que querías, la expresión regular necesita ser un poco mejorada.

Hay una solución rápida:

 x = eval('[ "A","B","C" , " D"]') 

Los espacios en blanco no deseados en los elementos de la lista se pueden eliminar de esta manera:

 x = [x.strip() for x in eval('[ "A","B","C" , " D"]')] 

Con numpy esto está funcionando de una manera muy simple.

 x = u'[ "A","B","C" , " D"]' list_string = str(x) import numpy as np print np.array(list_string) 

da

 >>> [ "A","B","C" , " D"] 

Sin importar nada;

 x = u'[ "A","B","C" , " D"]' ls = x.strip('][').split(',') 

Si sabe que sus listas solo contienen cadenas entrecomilladas, este ejemplo de reproducción le proporcionará su lista de cadenas cortadas (incluso conservando el Unicode-ness original).

 >>> from pyparsing import * >>> x =u'[ "A","B","C" , " D"]' >>> LBR,RBR = map(Suppress,"[]") >>> qs = quotedString.setParseAction(removeQuotes, lambda t: t[0].strip()) >>> qsList = LBR + delimitedList(qs) + RBR >>> print qsList.parseString(x).asList() [u'A', u'B', u'C', u'D'] 

Si sus listas pueden tener más tipos de datos, o incluso contener listas dentro de listas, entonces necesitará una gramática más completa, como esta en el wiki de pyparsing, que manejará tuplas, listas, ints, flotantes y cadenas citadas. Trabajará con las versiones de Python a 2.4.

Para completar aún más la respuesta de @Ryan usando json, una función muy conveniente para convertir Unicode es la que se publica aquí: https://stackoverflow.com/a/13105359/7599285

ex con comillas dobles o simples:

 >print byteify(json.loads(u'[ "A","B","C" , " D"]') >print byteify(json.loads(u"[ 'A','B','C' , ' D']".replace('\'','"'))) ['A', 'B', 'C', ' D'] ['A', 'B', 'C', ' D'] 

Me gustaría proporcionar una solución de patrones más intuitiva con expresiones regulares. La siguiente función toma como entrada una lista de cadenas que contiene cadenas arbitrarias.

Explicación paso a paso: elimine todo el espacio en blanco, el paréntesis y los value_separators (siempre que no formen parte de los valores que desea extraer, o haga que la expresión regular sea más compleja). Luego, divide la cadena limpia en comillas simples o dobles y toma los valores no vacíos (o valores indexados impares, cualquiera que sea la preferencia).

 def parse_strlist(sl): import re clean = re.sub("[\[\],\s]","",sl) splitted = re.split("[\'\"]",clean) values_only = [s for s in splitted if s != ''] return values_only 

muestra de prueba : “[’21’,” foo “‘6’, ‘0’,” A “]”

Entonces, siguiendo todas las respuestas, decidí cronometrar los métodos más comunes:

 from time import time import re import json my_str = str(list(range(19))) print(my_str) reps = 100000 start = time() for i in range(0, reps): re.findall("\w+", my_str) print("Regex method:\t", (time() - start) / reps) start = time() for i in range(0, reps): json.loads(my_str) print("json method:\t", (time() - start) / reps) start = time() for i in range(0, reps): ast.literal_eval(my_str) print("ast method:\t\t", (time() - start) / reps) start = time() for i in range(0, reps): [n.strip() for n in my_str] print("strip method:\t", (time() - start) / reps) regex method: 6.391477584838867e-07 json method: 2.535374164581299e-06 ast method: 2.4425282478332518e-05 strip method: 4.983267784118653e-06 

Así que al final regex gana!

puede guardarse el .strip () fcn simplemente cortando los primeros y últimos caracteres de la representación de cadena de la lista (vea la tercera línea a continuación)

 >>> mylist=[1,2,3,4,5,'baloney','alfalfa'] >>> strlist=str(mylist) ['1', ' 2', ' 3', ' 4', ' 5', " 'baloney'", " 'alfalfa'"] >>> mylistfromstring=(strlist[1:-1].split(', ')) >>> mylistfromstring[3] '4' >>> for entry in mylistfromstring: ... print(entry) ... type(entry) ... 1  2  3  4  5  'baloney'  'alfalfa'  

Supongamos que su cadena es t_vector = [34, 54, 52, 23] y desea convertir esto en una lista. Puedes usar los siguientes 2 pasos:

 ls = t_vector.strip('][') t_vector = ls.split(' ') 

t_vector contiene la lista.