Me preguntaba cuál es la forma más sencilla de convertir una string
lista como la siguiente a list
:
x = u'[ "A","B","C" , " D"]'
Incluso en caso de que el usuario ponga 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()
usando el operador dividido y verificar si no hay alfabetos. Pero el código se estaba volviendo muy torpe. ¿Hay alguna función rápida que no conozca?
Respuestas:
ast.literal_eval :
fuente
eval
, noast.literal_eval
.ast.literal_eval
es más seguro queeval
, pero en realidad no es seguro . Como explican las versiones recientes de los documentos : "Advertencia Es posible bloquear el intérprete de Python con una cadena lo suficientemente grande / compleja debido a las limitaciones de profundidad de pila en el compilador AST de Python". De hecho, puede ser posible ejecutar código arbitrario a través de un cuidadoso ataque de aplastamiento de la pila, aunque hasta donde yo sé nadie puede construir una prueba pública de concepto para eso.El
json
módulo es una mejor solución siempre que haya una lista de diccionarios en cadena . Lajson.loads(your_data)
función se puede usar para convertirla en una lista.similar
fuente
'["a","b"]'
pero no para"['a','b']"
.El
eval
es peligroso: no debe ejecutar la entrada del usuario.Si tiene 2.6 o más reciente, use ast en lugar de eval:
Una vez que tienes 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:
Esto no es tan bueno como la solución ast, por ejemplo, no maneja correctamente las comillas escapadas en cadenas. Pero es simple, no implica una evaluación peligrosa, y podría ser lo suficientemente bueno para su propósito si está en una Python más antigua sin ast.
fuente
eval
Es peligroso, no debes ejecutar la entrada del usuario"? Estoy usando 3.6eval
directamente, evaluará cualquier expresión de Python válida, que es potencialmente peligrosa.literal_eval
resuelve este problema evaluando solo estructuras literales de Python: cadenas, números, tuplas, listas, dictos, booleanos y Ninguno.fuente
Hay una solución rápida:
Los espacios en blanco no deseados en los elementos de la lista se pueden eliminar de esta manera:
fuente
Inspirado en algunas de las respuestas anteriores que funcionan con paquetes básicos de Python, comparé el rendimiento de algunos (usando Python 3.7.3):
Método 1: ast
Método 2: json
Método 3: no importar
Me decepcionó ver lo que consideraba que el método con la peor legibilidad era el método con el mejor rendimiento ... hay compensaciones a tener en cuenta al elegir la opción más legible ... para el tipo de cargas de trabajo para las que uso Python. valor de lectura sobre una opción ligeramente más eficiente, pero como siempre depende.
fuente
Si es solo una lista unidimensional, esto se puede hacer sin importar nada:
fuente
Asumiendo que todas sus entradas son listas y que las comillas dobles en la entrada en realidad no importan, esto se puede hacer con un simple regexp replace. Es un poco perl-y pero funciona como un encanto. Tenga en cuenta también que el resultado ahora es una lista de cadenas unicode, no especificó que lo necesitaba, pero parece tener sentido dada la entrada unicode.
La variable junkers contiene una expresión regular compilada (para la velocidad) de todos los caracteres que no queremos, usando] como carácter requirió algunos trucos de barra invertida. El re.sub reemplaza todos estos caracteres con 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 debe mejorarse un poco.
fuente
Si sabe que sus listas solo contienen cadenas entre comillas, este ejemplo de pyparsing le dará su lista de cadenas despojadas (incluso conservando la Unicode-ness original).
Si sus listas pueden tener más tipos de datos, o incluso contener listas dentro de las listas, necesitará una gramática más completa, como esta en el wiki de pyparsing, que manejará tuplas, listas, ints, flotantes y cadenas entre comillas. Funcionará con versiones de Python de nuevo a 2.4
fuente
parsePythonValue.py
ejemplo ahora está en GitHub en github.com/pyparsing/pyparsing/blob/master/examples/…Para completar aún más la respuesta de @Ryan usando json, una función muy conveniente para convertir Unicode es la publicada aquí: https://stackoverflow.com/a/13105359/7599285
ex con comillas dobles o simples:
fuente
Me gustaría proporcionar una solución de patrones más intuitiva con regex. La siguiente función toma como entrada una lista en cadena que contiene cadenas arbitrarias.
Explicación por pasos: elimina todos los espacios en blanco, los corchetes y los separadores de valores (siempre que no sean parte de los valores que desea extraer, de lo contrario, hacen que la expresión regular sea más compleja). Luego divide la cadena limpia entre comillas simples o dobles y toma los valores no vacíos (o valores indexados impares, sea cual sea la preferencia).
muestra de prueba : "['21'," foo "'6', '0'," A "]"
fuente
y con Python puro: no importar ninguna biblioteca
fuente
Puede encontrarse con este problema al tratar con datos raspados almacenados como Pandas DataFrame.
Esta solución funciona como un encanto si la lista de valores está presente como texto .
fuente
Entonces, siguiendo todas las respuestas, decidí cronometrar los métodos más comunes:
¡Así que al final regex gana!
fuente
puede guardarse el .strip () fcn simplemente cortando el primer y el último carácter de la representación de cadena de la lista (consulte la tercera línea a continuación)
fuente