Convertir string vers liste

Le
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
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Michel Claveau - NoSpam SVP ; merci
Le #18537301
Bonsoir !

Une liste de tuples, ça irait ?
Une solution :

s = "[[x = -3.641879138963874,y = 3.706332781387099],x
= -1.958120861036126,y= 2.627000551946235]]"
for i in ' []yx=': s=s.replace(i,'')
l=s.split(',')
L=zip(l[::2],l[1::2])


@-salutations
--
Michel Claveau
moky
Le #18537491
Michel Claveau - NoSpam SVP ; merci ha scritto:
Bonsoir !

Une liste de tuples, ça irait ?
Une solution :

s = "[[x = -3.641879138963874,y = 3.706332781387099],x =
-1.958120861036126,y= 2.627000551946235]]"
for i in ' []yx=': s=s.replace(i,'')
l=s.split(',')
L=zip(l[::2],l[1::2])



Tiens, je ne connaissais pas la commande zip. J'ai l'impression que tu
comptes sur le fait que chaque "couple" qu'il me faut sont exactement deux.

Désolé de n'avoir pas été plus général dans ma question, en fait je veux
pouvoir gérer des situations comme

[[a,b,c],[d,e,f],[g,h,i]]

Parce que je dois parfois résoudre des équations avec plus que deux
inconnues.

Au mieux, je peux supposer qu'il n'y a que deux niveaux d'imbrication,
et que tous les "paquets" ont un nombre égale d'éléments.

En attendant, j'ai codé ceci, que je dois encore rendre récursif pour
complètement résoudre le problème.

# Je suppose une chaîne de la forme [A,B,C,...], et retourne la liste
[A,B,C,...] où A,B,C,... sont des chaines.
def StringToListe(ch):
chaine = ch.replace(" ","")
niveau = 0
liste = []
a = ""
for c in chaine :
a = a+c
if c == "]" : niveau = niveau - 1
if c == "," and niveau == 1:
liste.append(a[0:len(a)-1])
a=""
if c == "[" : niveau = niveau + 1
liste.append(a[0:len(a)-1]) # On ne prend pas le dernier ]
liste[0] = liste[0][1:len(liste[0])] # Pour enlever le premier [
return liste

Je vais un peu voir si je ne peux pas creuser ton idée : d'abord tout
mettre en un bloc séparé par des virgules, puis faire un .split(",") et
enfin, les regrouper de façon ad hoc.

J'avoue être un peu étonné qu'il n'y ait pas un truc en python tout fait
qui interprète les enchevêtrements de "[","]" et "," comme des listes,
comme float() interprète une suite de "0123456789." comme un nombre.



Bon, je vais me coucher; j'ai la tête qui explose de python, LaTeX et
pstricks :)


Bonne nuit
Laurent
Méta-MCI \(MVP\)
Le #18537751
Re !

Si tu as des groupes de 3 valeurs, tu peux faire :
L = zip(l[::3],l[1::3],l[2::3])

nuit

Michel Claveau
Alain Ketterlin
Le #18539551
moky
[...]
J'avoue être un peu étonné qu'il n'y ait pas un truc en python tout
fait qui interprète les enchevêtrements de "[","]" et "," comme des
listes, comme float() interprète une suite de "0123456789." comme un
nombre.



eval() ?

-- Alain.
Méta-MCI \(MVP\)
Le #18540281
Salut !

eval() ?



J'avais bien pensé à eval. Car cette instruction est souvent utile pour
ce genre de traitement.
Mais l'exemple donné par Moky est mal formé (il manque un [ avant le
second x )
Comme j'ai supposé que cela provenait de la sortie du logiciel utilisé,
j'ai écarté le eval.

@+
--
Michel Claveau
moky
Le #18540381
Méta-MCI (MVP) ha scritto:
Salut !

eval() ?



J'avais bien pensé à eval. Car cette instruction est souvent utile pour
ce genre de traitement.
Mais l'exemple donné par Moky est mal formé (il manque un [ avant le
second x )



Exact; je ne sais pas dans quel copier-collé il a disparu, mais la
chaine que je compte traiter est bien
[[x=-3.732789400477221,y=2.409285524227547],[x=1.318485433306022,y=-0.82871116409504]]

de la forme
[[A,B],[C,D]]

Comme j'ai supposé que cela provenait de la sortie du logiciel utilisé,
j'ai écarté le eval.



Pour eval, j'ai essayé ceci, à tout hasard :

chL =
"[[x=-3.732789400477221,y=2.409285524227547],[x=1.318485433306022,y=-0.82871116409504]]"
L = eval(chL)
print L

Mais évidement ça n'a rien donné.
Je n'ai pas trouvé dans me documentation d'utilisation de eval()
autrement que dans des exemples comme eval(3+2) qui retourne 5.




Merci pour vous pencher sur mon problème
bon WE
Laurent
Alain Ketterlin
Le #18541311
moky
[...]
Exact; je ne sais pas dans quel copier-collé il a disparu, mais la
chaine que je compte traiter est bien
[[x=-3.73,y=2.40],[x=1.31,y=-0.82]]



(J'ai raccourci la ligne).

Bon, si ce n'est pas du python il n'y a pas de raison que Python sache
le lire. Donc, il faut ecrire un bout de code. Je te propose le code
ci-dessous, qui lit une chaine de caractères et construit un arbre
(une liste de listes de...) avec tout ce qu'il y trouve de la forme
x3 séparés par des virgules et entourés de crochets, et avec rien
d'autre (pas de blancs, etc.) Tout est conservé sous forme de chaînes
de caractères. Ca ne te conviendra surement pas directement (par
exemple sys.exit, etc.).

Si un expert pouvait jeter un oeil sur le code ci-dessous ça serait
sympa. Je débute en python.

-- Alain.


import sys
import re

# Lit une valeur dans la chaine s
# Renvoie un couple (reste,v) :
# - reste est la partie de la chaine non utilisee
# - v est la valeur lue
def read_val(s):
if s == "":
sys.exit("Malformed string")
elif s[0] == "[":
return read_list(s[1:])
else:
m = re.search("^([a-z]+)=([0-9.-]+)",s);
if m is None:
sys.exit("Malformed value")
return s[len(m.group(0)):], (m.group(1), m.group(2))

# Lit une liste dans la chaine s
# Renvoie un couple (reste,v) :
# - reste est la partie de la chaine non utilisee
# - v est la liste lue
def read_list(s):
s,v = read_val(s)
l = [v]
while s != "" and s[0] == ",":
s,v = read_val(s[1:])
l.append(v)
if s == "" or s[0] != "]":
sys.exit("Malformed list")
return s[1:],l


# Exemple
(r,l) = read_val("[[x=-3.73,y=2.40],[x=1.31,y=-0.82]]")
#(r,l) = read_val("[[x=1,y=2],[x=3,y=4],z=5,[[[[t=1]]]]]")
print l
print r
Méta-MCI \(MVP\)
Le #18545911
Bonsoir !

S'il manquait un caractère à cause des copié/collé ; si le résultats
sont bien formés ; si on accepte d'utiliser eval() ; alors, pourquoi ne
pas utiliser un dictionnaire ?

Un exemple :

def traite(*l, **d):
liste=[]
for i in l:
liste.append(i[1])
return liste,d

s =
"[[x=-3.732789400477221,y=2.409285524227547],[x=1.318485433306022,y=-0.82871116409504]]"
s=s.replace(' ','')
s=s.replace(']',')')
s=s.replace('[','traite(')
listes,bof=eval(s)
# visu résultat :
print listes[0]['x']
print listes[0]['y']
print
print listes[1]['x']
print listes[1]['y']


Et, ça se généralise sans problème.
Exemple (3x3) :

def traite(*l, **d):
liste=[]
for i in l:
liste.append(i[1])
return liste,d

s = "[[x=1,y,z1],[x=2,y",z"2],[x=3,y3,z33]]"
s=s.replace(' ','') #suppression des espaces nuisibles
s=s.replace(']',')') #conversion syntaxique
s=s.replace('[','traite(') #mise en place de la fonction
listes,bof=eval(s) #traitement des données (de la chaîne de caractères)
#on visualise le résultat :
for dic in listes:
for clef,valeur in dic.items():
print clef,valeur
print



@-salutations
--
Michel Claveau


PS : attention, j'ai parfois l'esprit un peu tordu.
Mais non, Python ne rend pas fou. Bzzzz. Couac ; hou-hou ; ZxxXzzy yy
xx h jqdch ghjg gzzzaa xzadzxxafaa...
Méta-MCI \(MVP\)
Le #18546151
Re !

On peut faire plus sobre, avec les listes en intention.
Exemple :

def traite(*l, **d):
return [i[1] for i in l],d

s = "[[x=1,y,z1],[x=2,y",z"2]]"
s=s.replace(' ','')
s=s.replace(']',')')
s=s.replace('[','traite(')
listes,bof=eval(s)
for dic in listes:
for clef,valeur in dic.items():
print clef,valeur
print


@-salutations
--
Michel Claveau
moky
Le #18546331
Méta-MCI (MVP) ha scritto:
Re !

On peut faire plus sobre, avec les listes en intention.
Exemple :
def traite(*l, **d):
return [i[1] for i in l],d

s = "[[x=1,y,z1],[x=2,y",z"2]]"
s=s.replace(' ','')
s=s.replace(']',')')
s=s.replace('[','traite(')
listes,bof=eval(s)
for dic in listes:
for clef,valeur in dic.items():
print clef,valeur
print




Merci beaucoup, je regarde ça.
Deux questions :
1. que signifie la syntaxe *l dans les paramètres d'une fonction ?
2. où puis-je trouver quelque chose de complet qui dit ce que rend
eval() dans chaque cas ?

Merci pour le coup de main !
Laurent
Publicité
Poster une réponse
Anonyme