Je me demandais quel était le moyen le plus simple de convertir une string
liste comme la suivante en un list
:
x = u'[ "A","B","C" , " D"]'
Même dans le cas où l'utilisateur place des espaces entre les virgules et des espaces à l'intérieur des guillemets. Je dois également gérer cela pour:
x = ["A", "B", "C", "D"]
en Python.
Je sais que je peux supprimer les espaces avec strip()
et en split()
utilisant l'opérateur de séparation et vérifier les non alphabets. Mais le code devenait très délicat. Y a-t-il une fonction rapide dont je ne suis pas au courant?
Réponses:
ast.literal_eval :
la source
eval
, nonast.literal_eval
.ast.literal_eval
est plus sûr queeval
, mais ce n'est pas vraiment sûr . Comme l' expliquent les versions récentes des documents : "Avertissement Il est possible de bloquer l'interpréteur Python avec une chaîne suffisamment grande / complexe en raison des limitations de profondeur de pile dans le compilateur AST de Python." En fait, il peut être possible d'exécuter du code arbitraire via une attaque minutieuse de destruction de pile, bien que, pour autant que je sache, personne n'a construit une preuve de concept publique pour cela.Le
json
module est une meilleure solution chaque fois qu'il y a une liste de dictionnaires stratifié . Lajson.loads(your_data)
fonction peut être utilisée pour la convertir en liste.De même
la source
'["a","b"]'
mais pas pour"['a','b']"
.C'est
eval
dangereux - vous ne devez pas exécuter la saisie utilisateur.Si vous avez 2.6 ou plus récent, utilisez ast au lieu de eval:
Une fois que vous avez cela,
strip
les cordes.Si vous utilisez une ancienne version de Python, vous pouvez être très proche de ce que vous voulez avec une simple expression régulière:
Ce n'est pas aussi bon que la solution ast, par exemple, il ne gère pas correctement les guillemets échappés dans les chaînes. Mais c'est simple, n'implique pas une évaluation dangereuse, et pourrait être assez bon pour votre objectif si vous êtes sur un Python plus ancien sans ast.
la source
eval
dangereux - vous ne devriez pas exécuter la saisie utilisateur.»? J'utilise 3.6eval
directement, il évaluera toute expression python valide, potentiellement dangereuse.literal_eval
résout ce problème en évaluant uniquement les structures littérales Python: chaînes, nombres, tuples, listes, dictés, booléens et Aucun.la source
Il existe une solution rapide:
Les espaces blancs indésirables dans les éléments de la liste peuvent être supprimés de cette manière:
la source
Inspiré de certaines des réponses ci-dessus qui fonctionnent avec les packages python de base, j'ai comparé les performances de quelques-uns (en utilisant Python 3.7.3):
Méthode 1: ast
Méthode 2: json
Méthode 3: aucune importation
J'ai été déçu de voir que ce que je considérais comme la méthode avec la pire lisibilité était la méthode avec les meilleures performances ... il y a des compromis à considérer lors de l'utilisation de l'option la plus lisible ... pour le type de charges de travail que j'utilise python pour moi habituellement valeur de lecture sur une option légèrement plus performante, mais comme d'habitude, cela dépend.
la source
S'il ne s'agit que d'une liste unidimensionnelle, cela peut être fait sans rien importer:
la source
En supposant que toutes vos entrées sont des listes et que les guillemets doubles dans l'entrée n'ont pas d'importance, cela peut être fait avec un simple regexp replace. C'est un peu perl-y mais fonctionne comme un charme. Notez également que la sortie est maintenant une liste de chaînes unicode, vous n'avez pas spécifié que vous en aviez besoin, mais cela semble logique étant donné l'entrée unicode.
La variable junkers contient une expression rationnelle compilée (pour la vitesse) de tous les caractères que nous ne voulons pas, en utilisant] comme caractère, il a fallu quelques trucs antislash. Le re.sub remplace tous ces caractères par rien, et nous séparons la chaîne résultante par des virgules.
Notez que cela supprime également les espaces à l'intérieur des entrées u '["oh no"]' ---> [u'ohno ']. Si ce n'est pas ce que vous vouliez, l'expression rationnelle doit être un peu gonflée.
la source
Si vous savez que vos listes contiennent uniquement des chaînes entre guillemets, cet exemple de mise en page vous donnera votre liste de chaînes supprimées (même en préservant la Unicode d'origine).
Si vos listes peuvent avoir plus de types de données, ou même contenir des listes dans des listes, alors vous aurez besoin d'une grammaire plus complète - comme celle-ci sur le wiki pyparsing, qui gérera les tuples, les listes, les entrées, les flottants et les chaînes entre guillemets. Fonctionnera avec les versions Python de retour à 2.4.
la source
parsePythonValue.py
exemple est maintenant sur GitHub à github.com/pyparsing/pyparsing/blob/master/examples/…Pour compléter la réponse de @Ryan en utilisant json, une fonction très pratique pour convertir unicode est celle publiée ici: https://stackoverflow.com/a/13105359/7599285
ex avec des guillemets doubles ou simples:
la source
Je voudrais fournir une solution de modelage plus intuitive avec regex. La fonction ci-dessous prend en entrée une liste stringifiée contenant des chaînes arbitraires.
Explication pas à pas: vous supprimez tous les espaces blancs, les crochets et les valeurs_séparateurs (à condition qu'ils ne fassent pas partie des valeurs que vous souhaitez extraire, sinon rendre l'expression rationnelle plus complexe). Ensuite, vous divisez la chaîne nettoyée entre guillemets simples ou doubles et prenez les valeurs non vides (ou les valeurs indexées impaires, quelle que soit la préférence).
exemple de test : "['21'," foo "'6', '0'," A "]"
la source
et avec du python pur - ne pas importer de bibliothèques
la source
Vous pouvez rencontrer un tel problème lorsque vous traitez des données récupérées stockées en tant que Pandas DataFrame.
Cette solution fonctionne comme un charme si la liste de valeurs est présente sous forme de texte .
la source
Donc, en suivant toutes les réponses, j'ai décidé de chronométrer les méthodes les plus courantes:
Donc, finalement, regex gagne!
la source
vous pouvez vous enregistrer le fcn .strip () en coupant simplement les premier et dernier caractères de la représentation sous forme de chaîne de la liste (voir la troisième ligne ci-dessous)
la source