Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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
Michel Claveau - NoSpam SVP ; merci
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
Avatar
moky
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
Avatar
Méta-MCI \(MVP\)
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
Avatar
Alain Ketterlin
moky writes:

[...]
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.
Avatar
Méta-MCI \(MVP\)
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
Avatar
moky
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
Avatar
Alain Ketterlin
moky writes:

[...]
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
Avatar
Méta-MCI \(MVP\)
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...
Avatar
Méta-MCI \(MVP\)
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
Avatar
moky
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
1 2 3