IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Transformer une string en un dictionnaire


Sujet :

Python

  1. #1
    Futur Membre du Club
    Inscrit en
    Février 2004
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut Transformer une string en un dictionnaire
    Bonjour,

    J'essaye sans succes pour l'instant de transformer une string formatée exactement comme un dictionnaire python en une structure dict. Ex.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s = "{'a':{'b':'c', 'd':'e'}}"
    j'aimerai avoir à partir de s l'équivalent de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    d = {'a':{'b':'c', 'd':'e'}}
    il y a bien la fonction exec mais je la trouve un peu radicale et très problématique dans mon cas (la string vient du web).

    Je me demande donc si il existe pas une fonction ou une expression régulière permettant de parser une telle string en un dict.

    Merci d'avance pour votre aide

    Nicolas

  2. #2
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,

    les expressions régulières ne vont pas être le plus indiqué pour ce type d'expression récursive. Et si tu ne veux ou peux utiliser exec(), il ne te reste plus qu'à écrire un analyseur. Selon l'expression que tu as donnée en exemple, on peut déduire la grammaire suivante (grossièrement) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    dictionnaire ::= "{" paire (,paire)* "}"
    paire ::= cle ":" valeur
    cle ::= caractère
    caractère ::= "'" alpha "'"
    valeur ::= caractère | dictionnaire
    Il n'y a plus qu'à traduire cette grammaire en Python :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    # -*- coding: iso-8859-1 -*-
     
     
    def nextToken(expr):
        for c in expr:
            yield c
     
    def dictionnaire():
        global token
        if token != '{':
            raise "{ attendu !"
        d = {}
        token = it_token.next()
        cle, valeur = paire()
        d[cle] = valeur
        while token == ',':
            token = it_token.next()
            cle, valeur = paire()
            d[cle] = valeur        
        if token != '}':
            raise "} attendu !"
        return d
     
    def paire():
        global token
        nouv_cle = cle()
        token = it_token.next()    
        if token != ':':
            raise ': attendu !'
        token = it_token.next()    
        nouv_valeur = valeur()
        token = it_token.next()
        return nouv_cle, nouv_valeur
     
    def cle():
        return caractere()
     
    def caractere():
        global token
        if token != '\'':
            raise '\' attendu !'
        token = it_token.next()
        cle = token
        token = it_token.next()
        if token != '\'':
            raise '\' attendu !'
        return cle
     
    def valeur():
        global token
        if token == '\'':
            return caractere()
        elif token == '{':
            return dictionnaire()
        else:
            raise 'erreur de syntaxe'
     
    expr = "{'a':{'b':'c','d':'e'}}"
    it_token = nextToken(expr)
    token = it_token.next()
    d = dictionnaire()
    print d
    Si tu dois avoir des chaînes à plusieurs caractères plutot qu'un seul, autoriser les espaces entre les tokens ou les dictionnaires vides, il suffit d'adapter l'algorithme mais le principe reste le même.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  3. #3
    Membre émérite
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Points : 2 533
    Points
    2 533
    Par défaut
    Une solution qui me parait simple et a priori qui ne pose pas de problème de sécurité serait peut etre celle là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    import UserDict
     
    value = "{'a':{'b':'c', 'd':'e'}}"
     
    try:
      a = UserDict.UserDict(eval(value))
    except:
      print "Ce n'est pas un dictionnaire"
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  4. #4
    Futur Membre du Club
    Inscrit en
    Février 2004
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Merci à vous deux pour ces responses rapides.

    GrandFather : Effectivement il existe toujours cette solution mais je voulais justement éviter de devoir écrire cette sorte de code, mais qui est effectivement toujours possible et je te remercie pour l'exemple d'algorithme .

    DelphiManiac :
    effectivement j'utilise actuellement eval().
    J'ai cependant 2 interogations.
    Premierement y a-t'il une différence entre


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UserDict.UserDict(eval(value))
    et
    dict(eval(value))
    j'ai lu que UserDict ne devais être utiliser que pour backward compatibilté.

    Deuxièment :
    quel type de code peut être executé avec eval, car dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UserDict.UserDict(eval(value))
    ou
    dict(eval(value))
    le eval va être interpreter avant la création du dictionnaire. Si un code dangereux est envoyé à eval il sera quand même interpreter. D'où l'importance du type de code pouvant être passé à eval.
    Merci encore

  5. #5
    Membre émérite
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Points : 2 533
    Points
    2 533
    Par défaut
    Après vérification, l'eval est toujours effectué, donc il y a un risque d'exécuter une code non prévu.

    Par contre, ne serait-il pas suffisant et assez simple de juste vérifier que la chaine reçu commence bien par un { et fini par un } avant de la passer en eval ?

    Il ne me semble pas possible d'exécuter un quelconque code à partir du moment ou celui ci est encadrer par des { }.
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  6. #6
    Futur Membre du Club
    Inscrit en
    Février 2004
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Effectivement je peux faire une petite vérification avant, c'est une bonne solution. Je pense que dans mon cas le eval est encore la solution la plus simple.

    Merci pour ces réponses.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Transformer une string en int
    Par blueice dans le forum AppleScript
    Réponses: 1
    Dernier message: 28/09/2014, 18h55
  2. Réponses: 3
    Dernier message: 18/02/2013, 05h15
  3. Transformer une String en fonction
    Par Jevil dans le forum MATLAB
    Réponses: 12
    Dernier message: 07/02/2008, 23h46
  4. transformer une string en tableau
    Par alexis.gruet dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 05/04/2007, 23h12
  5. Transformer une String en Unicode
    Par annemarie dans le forum Delphi
    Réponses: 3
    Dernier message: 28/02/2007, 17h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo