OVH Cloud OVH Cloud

Convertir string vers liste

22 réponses
Avatar
moky
Bonjour à toutes et à tous


Si j'ai une chaîne de caractère a="23", je peux faire x=int(a) pour
avoir un nombre x.
J'aimerais faire la même chose avec des listes. J'ai une chaîne de
caractère
[[x = -3.641879138963874,y = 3.706332781387099],x =
-1.958120861036126,y= 2.627000551946235]]

Et je voudrais en faire une liste telle que

L[0] soit la liste [x = -3.641879138963874,y = 3.706332781387099]



Pour le contexte, je suis en train de vouloir résoudre des équations
avec maxima, et j'analyse la sortie pour créer une liste de solutions.
Au final, à partir de la chaîne
[[x = -3.641879138963874,y = 3.706332781387099],x =
-1.958120861036126,y= 2.627000551946235]]

je voudrais avoir la liste
[[-3.641879138963874,3.706332781387099] ,
[-1.958120861036126,2.627000551946235]]

avec
L[0][0]=-3.641879138963874
L[0][1]=3.706332781387099
L[1][0]=-1.958120861036126
L[1][1]=2.627000551946235

Pour l'instant, je fais des manipulations à coup de recherches des
caractères "[","]" et ",", mais c'est un peu l'horreur.

Si vous avez des idées de comment faire facilement, je suis preneur

Bonne nuit
Laurent

10 réponses

1 2 3
Avatar
Méta-MCI \(MVP\)
Salut !

1. que signifie la syntaxe *l dans les paramètres d'une fonction ?



*l signifie que les paramètres par position vont être traités comme une
liste.
**d signifie que les paramètres nommés vont être traités comme un
dictionnaire (c'est aussi un moyen rusé de définir un dictionnaire).
Mais bon, si tu te poses ce genre de question, mon exemple de code
risque de ne pas être très facile à comprendre. Quoique, avec une
fonction de deux lignes...

2. où puis-je trouver quelque chose de complet qui dit ce que rend
eval() dans chaque cas ?



eval n'a qu'un cas de fonctionnement. Il traite une chaine de caractères
comme un script qui retourne une valeur.
Pour mieux suivre ce qui se passe, quelques print bien placés sont
irremplaçables.


@-salutations
--
Michel Claveau
Avatar
moky
> eval n'a qu'un cas de fonctionnement. Il traite une chaine de caractères
comme un script qui retourne une valeur.
Pour mieux suivre ce qui se passe, quelques print bien placés sont
irremplaçables.




Alors pourquoi chercher loin et ne pas faire ceci ? (qui fonctionne,
j'ai testé)

#! /usr/bin/python
# -*- coding: utf8 -*-

chaine = "[ ["a","b"],["c"] ]"
print chaine
K = eval(chaine)
print K

Dans mon cas, je n'ai qu'à remplacer tous les [ par [" dans la chaîne
avant de la passer par eval.
Après, convertir la chaîne "x=0.15" en un assignation de la valeur 0.15
à une variable de mon choix ne sera pas difficile (sur base d'un
.split("=")).

Je teste ça en grandeur nature et je vous tient au courant.

Merci pour tout !
Laurent


PS : Est-ce que tu pourrais m'indiquer un TFM que je pourrais R à propos
de ces l* et d** ?
Avatar
moky
Eh bien voila, le code suivant répond à mes attentes :

def StringToListe(ch):
chaine = ch.replace("
","").replace("[","["").replace("]",""]").replace(",","","")
L = eval(chaine)
return L

Évidement, si il y a un "," qui fait partie d'un élément, on ne peut
rien contre !

Encore merci pour cette commande eval(); ça vaut de l'or ce truc :)


Bon dimanche
Laurent
Avatar
Mihamina Rakotomandimby (R12y)
Alain Ketterlin wrote:
Bon, si ce n'est pas du python il n'y a pas de raison que Python sache
le lire.



Je n'ai pas compris cette phrase.
Avatar
Alain Ketterlin
"Mihamina Rakotomandimby (R12y)" writes:

Bon, si ce n'est pas du python il n'y a pas de raison que Python sache
le lire.



Je n'ai pas compris cette phrase.



eval() utilise le parser python "standard", celui qui lit le programme
source. On ne peut donc fournir à eval() que quelque chose qui soit
conforme à la syntaxe de python (ce doit être une expression qui
pourrait apparaître dans un code source). Le problème dont nous
parlions consistait à faire "comprendre" à eval() quelque chose qui
utilise une autre syntaxe.

A partir de là il y a deux solutions. Soit écrire un petit bout de
code qui analyse lui-même le texte (ce que j'ai proposé), soit
appliquer au texte des transformations de façon à l'amener à quelque
chose qui soit une expression python valide, passée ensuite à eval()
(ce qui semble être la solution retenue).

-- Alain.
Avatar
Bruno Desthuilliers
moky a écrit :
eval n'a qu'un cas de fonctionnement. Il traite une chaine de
caractères comme un script qui retourne une valeur.
Pour mieux suivre ce qui se passe, quelques print bien placés sont
irremplaçables.




Alors pourquoi chercher loin et ne pas faire ceci ? (qui fonctionne,
j'ai testé)

#! /usr/bin/python
# -*- coding: utf8 -*-

chaine = "[ ["a","b"],["c"] ]"
print chaine
K = eval(chaine)
print K




Attention : n'emploie "eval" que sur des sources dont tu es *absolument*
sûr. A moins, bien sûr, qu'une énorme faille de sécurité ne te dérange
pas !-)

(snip)

PS : Est-ce que tu pourrais m'indiquer un TFM que je pourrais R à propos
de ces l* et d** ?



http://docs.python.org/tutorial/controlflow.html#more-on-defining-functions
Avatar
moky
>
Attention : n'emploie "eval" que sur des sources dont tu es *absolument*
sûr. A moins, bien sûr, qu'une énorme faille de sécurité ne te dérange
pas !-)



Ah oui; c'est vrai que je n'y avait pas pensé. Je vais revoir ma copie.

En l'occurrence, ce que je donne à eval() est le résultat d'un grep dans
la sortie du programme maxima ... le risque n'est sans doute pas énorme,
mais tout de même, ce n'est pas sérieux.

Merci pour l'avis
Laurent
Avatar
Michel Claveau - NoSpam SVP ; merci
Salut !

une énorme faille de sécurité



eval() n'est ni plus, ni moins, sécurisé que import, runpy, execfile,
pdb.run, execXXX, Tkinter.Tk().eval(), etc.

En fait, Python n'est pas conçu avec une sécurité interne importante.
Alors, AMHA, eval() n'est qu'un point parmi d'autres, et se focaliser
dessus, ça me semble plus alarmiste que réaliste.

@-salutations
--
Michel Claveau
Avatar
Michel Claveau - NoSpam SVP ; merci
Salut !

Alors pourquoi chercher loin et ne pas faire ceci ? (qui fonctionne,
j'ai testé)...



Parce que, là encore, les spécifs ont changé (la chaîne analysée n'a
plus la même forme).
Si ça peut changer aussi souvent, autant faire un parseur. C'est un peu
la démarche d' Alain Ketterlin

@-salutations
--
Michel Claveau
Avatar
Bruno Desthuilliers
Michel Claveau - NoSpam SVP ; merci a écrit :
Salut !

une énorme faille de sécurité



eval() n'est ni plus, ni moins, sécurisé que import, runpy, execfile,
pdb.run, execXXX, Tkinter.Tk().eval(), etc.



Tout à fait. Et ?

En fait, Python n'est pas conçu avec une sécurité interne importante.
Alors, AMHA, eval() n'est qu'un point parmi d'autres, et se focaliser
dessus, ça me semble plus alarmiste que réaliste.



Je ne me focalise pas dessus, j'attire l'attention de l'OP sur le risque
qu'il y a à passer une entrée utilisateur à eval dans ce cas
d'utilisation. Si la solution proposée avait reposé sur n'importe quelle
autre des options que tu cites (à part éventuellement Tkinter.yadda - je
ne suis pas utilisateur donc je ne connais pas), ma réaction auarit été
la même. Ceci étant, il est plus courant de voire ce genre de faille
dans l'utilisation d'un eval ou d'un exec que sur un import ou autre.
Pour ce que ça vaut, tu a oublié de mentionner os.system() etc, ou les
injections SQL, ou <ami-lecteur-ajoute-ta-faille-favorite-ici>.

Quant à taxer de "plus alarmiste que réaliste" le fait de rappeler une
règle de sécurité *de base* (ne pas faire confiance aux entrées
utilisateur), je trouve ça pour le moins surprenant.
1 2 3