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 :

Création dynamique d'un dictionnaire


Sujet :

Python

  1. #1
    Nouveau membre du Club Avatar de dca_marshall
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 46
    Points : 37
    Points
    37
    Par défaut Création dynamique d'un dictionnaire
    Bonjour,

    Big picture
    Je souhaite alimenter un dictionnaire, sur la base d'un Parser Lexx/Yacc.
    Toutefois je vous fais grâce du contenu du Parser.
    Et actuellement, il me renvoi bien ce que j'attendais.

    Je souhaiterai donc créer ce dictionnaire, via des "pointeurs" (ou référence) pour alimenter chaque valeur de clé, dans les items des listes.
    Toutefois, la profondeur de ce dictionnaire sera très variable (selon ce que découvre le Parser).

    J'ai donc fait un petit code, qui permet de lire un dictionnaire, pour la simulation du Parser (dict1), afin d'en alimenter un autre.
    Mais je suis "sec" sur ce que je dois mettre pour alimenter le second dictionnaire (dict2).
    Pour info, je fais très bien cela en Perl, mais là j'avoue être perdu...

    Si vous pouviez me mettre sur la bonne piste, je serai un homme heureux

    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
    63
    64
    65
    66
    67
    68
     
    #!/usr/bin/env python3
    import json
     
    dict2 = {}
    current = { 'pad': 0 }
    dict1 = {
       'level1': [
     
          {
             'prp1': 'foo1',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level2': [
                {
                   'prp1': 'foo12',
                   'prp2': 'bar12',
                },
                {
                   'prp1': 'foo13',
                   'prp2': 'bar13',
                },
             ],
          },
     
          {
             'prp1': 'foo2',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level2': [
                {
                   'prp1': 'foo22',
                   'prp2': 'bar22',
                },
                {
                   'prp1': 'foo23',
                   'prp2': 'bar23',
                },
             ],
          },
     
       ],
    }
     
     
    def _readList(myList):
       for myItem in myList:
          print("{}{}".format( '   ' * current['pad'], '---' ))
          if isinstance(myItem, dict):
             _readDict(myItem)
     
     
     
     
     
    def _readDict(currentDict):
       for k,v in currentDict.items():
          if isinstance(v, list):
             print("{}{}".format( '   ' * current['pad'], k ))
             current['pad']+=1
             _readList(v)
             current['pad']-=1
          else:
             print("{}{}={}".format( '   ' * current['pad'], k, v ))
     
     
    _readDict(dict1)
    print(json.dumps(dict2))
    Note:
    Les pad dans les print, sont juste là pour l'indentation de sortie et les tirets pour montrer les ruptures.
    Et comme je n'aime pas trop les "global", j'ai mis la valeur du pad, dans in dictionnaire.

    Aparté:
    Du reste, je trouve plutôt étrange, de permettre, à un dictionnaire ou une liste, d'être "global" et pas une variable?!
    Je n'ai peut être pas compris un truc... ?

    La sortie donne ceci :
    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
     
    level1
       ---
       prp1=foo1
       prp2=bar
       prp3=zzz
       level2
          ---
          prp1=foo12
          prp2=bar12
          ---
          prp1=foo13
          prp2=bar13
       ---
       prp1=foo2
       prp2=bar
       prp3=zzz
       level2
          ---
          prp1=foo22
          prp2=bar22
          ---
          prp1=foo23
          prp2=bar23
    {}
    Merci d'avance de votre aide

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par dca_marshall Voir le message
    J'ai donc fait un petit code, qui permet de lire un dictionnaire, pour la simulation du Parser (dict1), afin d'en alimenter un autre.
    Mais je suis "sec" sur ce que je dois mettre pour alimenter le second dictionnaire (dict2).
    Vous voulez y mettre quoi dans dict2? Il n'y a rien dans votre code ni dans votre prose qui le mentionne: on ne va pas l'inventer!
    note: vous avez le module pprint pour afficher les structures composites avec indentation (ou pas).

    Citation Envoyé par dca_marshall Voir le message
    Aparté:
    Du reste, je trouve plutôt étrange, de permettre, à un dictionnaire ou une liste, d'être "global" et pas une variable?!
    Je n'ai peut être pas compris un truc... ?

    Une variable peut être locale ou globale.
    Un objet tel qu'un dictionnaire ou une liste seront associés à une ou plusieurs variables (pour exister) mais ne sont ni globaux ni locaux (çà c'est une propriété des variables). Ils ont juste une durée de vie et un état.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Nouveau membre du Club Avatar de dca_marshall
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    Bonjour wiztricks,

    Merci pour ta réponse et les infos (pprint et le global).
    Juste un dernier truc là dessus : Il faut préciser dans chaque fonction, que la variable que l'on souhaite adresser est global, avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    machin = 'bidule'
    def myFunction():
       global machin
       machin = 'truc'
    alors qu'avec un dictionnaire, ce n'est pas nécessaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    myDict = { 'machin': 'bidule' }
    def myFunction():
       myDict['machin'] = 'truc'
    C'est juste cela que je trouve étrange. Mais bon, je ne vais pas en faire un fromage...



    Sinon, c'est vrai que j'ai pas été très clair (toutes mes confuses)
    Sur la base de ce code, je veux juste alimenter le dict2, avec exactement le même contenu que dict1 (mais sans utiliser "copy").
    Le but étant de savoir comment adresser un "pointeur" sur dict2, lorsqu'il est alimenté à différents niveaux.

    Donc le code donne juste les "moment" où l'alimentation de dict2 devrait être faite.

    Et du coup, comme je n'ai jamais réussi à le faire, je demande votre aide.

    Merci encore.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Lorsque vous écrivez machin = 'truc', vous essayez d'associer un nouvel objet à "machin". Par défaut dans une fonction "machin" sera variable locale... sauf à le préciser via la déclaration "global".

    Quand vous écrivez myDict['machin'] = 'truc', vous modifiez juste la clef du dictionnaire que vous récupérez via "myDict" (qui est variable globale... mais vous accédez à l'objet associé, vous ne modifiez pas l'association).

    Un autre aspect important est qu'une chaine de caractère ('truc') n'est pas mutable. Une fois l'association faite avec "machin", impossible de la modifier sans la remplacer.
    Les dictionnaires et les listes sont eux des objets mutables: vous pouvez les modifier sans avoir à remplacer l'ancien par le nouveau.

    Sur la base de ce code, je veux juste alimenter le dict2, avec exactement le même contenu que dict1 (mais sans utiliser "copy").
    Le but étant de savoir comment adresser un "pointeur" sur dict2, lorsqu'il est alimenté à différents niveaux.
    dict2 = dict1!
    Mais vous aurez alors deux variables associé au même objet.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Nouveau membre du Club Avatar de dca_marshall
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    En fait, le but n'est pas de copier un dictionnaire dans un autre.
    J'ai juste simulé le Parser avec les boucle récursives, pour créer les "moment" d'alimentation de dict2.
    Je voudrai savoir quoi mettre au niveau syntaxe, pour alimenter dict2.

    J'ai fait plusieurs essais, mais sans succès...
    Il faut donc mettre les instructions d'alimentation de dict2, juste au dessous des print.

    Je met des commentaires dans le code pour cette visualisation
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    #!/usr/bin/env python3
    import json
     
    dict2 = {}
    current = { 'pad': 0 }
    dict1 = {
       'level1': [
     
          {
             'prp1': 'foo1',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level2': [
                {
                   'prp1': 'foo12',
                   'prp2': 'bar12',
                },
                {
                   'prp1': 'foo13',
                   'prp2': 'bar13',
                },
             ],
          },
     
          {
             'prp1': 'foo2',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level2': [
                {
                   'prp1': 'foo22',
                   'prp2': 'bar22',
                },
                {
                   'prp1': 'foo23',
                   'prp2': 'bar23',
                },
             ],
          },
     
       ],
    }
     
     
    def _readList(myList):
       for myItem in myList:
          print("{}{}".format( '   ' * current['pad'], '---' ))
          #-------------------------------------------
          # Tien ! Voici un nouvel item de list...
          # Alors je dois surement faire un append sur
          # le pointeur courant
          #-------------------------------------------
          if isinstance(myItem, dict):
             _readDict(myItem)
     
     
     
     
     
    def _readDict(currentDict):
       for k,v in currentDict.items():
          if isinstance(v, list):
             print("{}{}".format( '   ' * current['pad'], k ))
             #-------------------------------------------
             # Ha bah ici, c'est une nouvelle clé de liste
             # Il faut donc créer cette clé au format list
             # ci elle n'existe pas
             #-------------------------------------------
             current['pad']+=1
             _readList(v)
             current['pad']-=1
          else:
             print("{}{}={}".format( '   ' * current['pad'], k, v ))
             #-------------------------------------------
             # Et là c'est juste une clé valeur
             # Toujours sur le pointeur courant je dois faire
             # dict2reference[k] = v
             #-------------------------------------------
     
     
    _readDict(dict1)
    print(json.dumps(dict2))

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par dca_marshall Voir le message
    J'ai fait plusieurs essais, mais sans succès...
    Il faut donc mettre les instructions d'alimentation de dict2, juste au dessous des print.
    Si c'est pas dict2[k] = v, il va falloir préciser non pas ce que vous voulez faire mais le résultat que vous cherchez à obtenir.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Nouveau membre du Club Avatar de dca_marshall
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    OK merci de ta patience

    Alors voilà, je viens de refaire le code avec les lignes qui me semble nécessaires.
    Ces nouvelles lignes sont encadrées de commentaires, par la droite.

    Je pense qu'elles sont facilement compréhensible et démontrer le besoin.

    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
     
    #!/usr/bin/env python3
    import json
     
    dict2 = {}
    current = { 'pad': 0 }
    dict1 = {
       'level1': [
     
          {
             'prp1': 'foo1',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level2': [
                {
                   'prp1': 'foo12',
                   'prp2': 'bar12',
                },
                {
                   'prp1': 'foo13',
                   'prp2': 'bar13',
                },
             ],
          },
     
          {
             'prp1': 'foo2',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level2': [
                {
                   'prp1': 'foo22',
                   'prp2': 'bar22',
                },
                {
                   'prp1': 'foo23',
                   'prp2': 'bar23',
                },
             ],
          },
     
       ],
    }
     
     
    def _readList(myList, newDict):
       for myItem in myList:
          print("{}{}".format( '   ' * current['pad'], '---' ))
     
          #-------------------------------------------
          # Tien ! Voici un nouvel item de list...
          # Alors je dois surement faire un append sur
          # le pointeur courant
          #------------------------------------------#
          newDict.append( {} )                       #
          newDict = newDict[-1]                      #
          #------------------------------------------#
     
          if isinstance(myItem, dict):
             _readDict(myItem, newDict)
     
     
     
    def _readDict(currentDict, newDict):
       saveDict = newDict
       for k,v in currentDict.items():
          if isinstance(v, list):
             print("{}{}".format( '   ' * current['pad'], k ))
     
             #-------------------------------------------
             # Ha bah ici, c'est une nouvelle clé de liste
             # Il faut donc créer cette clé au format list
             # ci elle n'existe pas
             #------------------------------------------#
             if not k in newDict:                       #
                newDict[k] = []                         #
             newDict = newDict[k]                       #
             #------------------------------------------#
     
             current['pad']+=1
             _readList(v, newDict)
     
             #------------------------------------------#
             newDict = saveDict                         #
             #------------------------------------------#
     
             current['pad']-=1
          else:
             print("{}{}={}".format( '   ' * current['pad'], k, v ))
     
             #-------------------------------------------
             # Et là c'est juste une clé valeur
             # Toujours sur le pointeur courant je dois faire
             # dict2reference[k] = v
             #------------------------------------------#
             newDict[k] = v                             #
             print('dict2' + json.dumps(                #
                dict2,                                  #
                indent=4,                               #
                sort_keys=True)                         #
             )                                          #
             #------------------------------------------#
     
    _readDict(dict1, dict2)
    print('dict2' + json.dumps(dict2, indent=4, sort_keys=True))
    Mais voilà, on voit bien que ça avance dans l'arborescence, mais je n'arrive pas trouver le moment de retour, pour revenir sur un parent.
    J'ai fait un Dump JSON de dict2 à chaque création de clé/valeur.

    Mais bam, un peu plus loin !!
    Ca arrive, dès que je dois revenir sur le parent dans l'arborescence de dict2.
    Ceci en reprenant la sauvegarde du pointeur de dict2.

    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
    level1
       ---
       prp1=foo1
    dict2{
        "level1": [
            {
                "prp1": "foo1"
            }
        ]
    }
       prp2=bar
    dict2{
        "level1": [
            {
                "prp1": "foo1",
                "prp2": "bar"
            }
        ]
    }
       prp3=zzz
    dict2{
        "level1": [
            {
                "prp1": "foo1",
                "prp2": "bar",
                "prp3": "zzz"
            }
        ]
    }
       level2
          ---
          prp1=foo12
    dict2{
        "level1": [
            {
                "level2": [
                    {
                        "prp1": "foo12"
                    }
                ],
                "prp1": "foo1",
                "prp2": "bar",
                "prp3": "zzz"
            }
        ]
    }
          prp2=bar12
    dict2{
        "level1": [
            {
                "level2": [
                    {
                        "prp1": "foo12",
                        "prp2": "bar12"
                    }
                ],
                "prp1": "foo1",
                "prp2": "bar",
                "prp3": "zzz"
            }
        ]
    }
          ---
    Traceback (most recent call last):
      File "./testDict.py", line 103, in <module>
        _readDict(dict1, dict2)
      File "./testDict.py", line 80, in _readDict
        _readList(v, newDict)
      File "./testDict.py", line 59, in _readList
        _readDict(myItem, newDict)
      File "./testDict.py", line 80, in _readDict
        _readList(v, newDict)
      File "./testDict.py", line 54, in _readList
        newDict.append( {} )                       #
    AttributeError: 'dict' object has no attribute 'append'

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par dca_marshall Voir le message
    Alors voilà, je viens de refaire le code avec les lignes qui me semble nécessaires.
    Ces nouvelles lignes sont encadrées de commentaires, par la droite.
    On écrit ce qu'on veut obtenir avant d'écrire le code... puis on écrit le code et on teste qu'on obtient bien ce qui est attendu.
    Et pour l'instant, vous n'avez toujours pas dit à quoi doit ressembler dict2 sinon râler que çà ne produit pas le résultat que vous attendez.
    Et comme je ne suis pas dans votre tête...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Nouveau membre du Club Avatar de dca_marshall
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    Je voudrai que dict2 soit parfaitement égal à dict1, mais sans passer par une copy.
    Seulement en utilisant ce code (qui simule le Parser).

  10. #10
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par dca_marshall Voir le message
    Je voudrai que dict2 soit parfaitement égal à dict1, mais sans passer par une copy.
    Seulement en utilisant ce code (qui simule le Parser).
    Et bien donc dans ce cas en écrivant tout simplement

    vous ne réaliser aucune copie. Vous dites simplement que dict2 est un pointeur qui pointe sur le même objet que dict1.

    Regardez cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    dict1 = { 'a':0 , 'b':1 }
    dict2  = dict1 
    print(dict1, dict2)
    dict2['a']=7
    print(dict1, dict2)
    dict1['b']=53
    print(dict1, dict2)
    Si vous exécutez ce code vous vous rendrez compte que modifier dict2 impacte dict1. Et vice versa. Car dict2 et dict1 ne sont que des pointeurs vers le même objet en mémoire. Par défaut python ne fait aucune copie sur les objets mutables. Le signe égal affecte simplement un nouveau pointeur. Et donc pour moi répond parfaitement au besoin que vous exprimez.

    Si on veut forcer une copie il existe un module pour ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     from copy import deepcopy
     
    dict1 = { 'a':0 , 'b':1 }
    dict2  = deepcopy(dict1) 
    print(dict1, dict2)
    dict2['a']=7
    print(dict1, dict2)
    dict1['b']=53
    print(dict1, dict2)

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par dca_marshall Voir le message
    Je voudrai que dict2 soit parfaitement égal à dict1, mais sans passer par une copy.
    Seulement en utilisant ce code (qui simule le Parser).
    Le code fait une descente récursive dans un objet qui est un composite (et pas un simple dico). Si vous voulez créer une structure "en parallèle", il faut que les fonctions puissent accéder au parent du nœud courant (à créer via une class qui enrobe cela ainsi que des méthodes d'ajout) ou qu'elles remontent le sous-arbre que l'appelant saura insérer où il faut (puis qu'il sait d'où on part). Vous avez d'abord un soucis d'algo. et/où de structures de données (et je ne comprends pas comment vous pouvez faire çà en Perl) qui n'a rien à voir avec la programmation Python.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Nouveau membre du Club Avatar de dca_marshall
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    Bonjour,

    Certes je dois merder en Python.
    Mais voici comment je le ferai en Perl.

    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    #!/usr/bin/env perl -w
    use strict;
    use warnings;
    use Data::Dumper;
     
    my %dict2 = ();
    my $currentPad = 0;
    my %dict1 = (
       'level1' => [
     
          {
             'prp1' => 'foo1',
             'prp2' => 'bar',
             'prp3' => 'zzz',
             'level2' => [
                {
                   'prp1' => 'foo12',
                   'prp2' => 'bar12',
                },
                {
                   'prp1' => 'foo13',
                   'prp2' => 'bar13',
                },
             ],
          },
     
          {
             'prp1' => 'foo2',
             'prp2' => 'bar',
             'prp3' => 'zzz',
             'level2' => [
                {
                   'prp1' => 'foo22',
                   'prp2' => 'bar22',
                },
                {
                   'prp1' => 'foo23',
                   'prp2' => 'bar23',
                },
             ],
          },
     
       ],
    );
     
     
    sub _readList(@) {
       my ($myList, $newDict) = @_;
       for my $myItem ( @{ $myList } ) {
          printf("%s%s\n", '   ' x $currentPad, '---' );
          push(@{ $newDict }, {});
          if ( ref($myItem) eq 'HASH' ) {
             _readDict($myItem, @{ $newDict }[-1]);
          }
       }
    }
     
     
    sub _readDict(@) {
       my ($currentDict, $newDict) = @_;
       while (my ($k, $v) = each(%{ $currentDict })) {
          if ( ref($v) eq 'ARRAY' ) {
             printf("%s%s\n", '   ' x $currentPad, $k );
             $currentPad++;
             _readList($v, \@{ $newDict->{$k} });
             $currentPad--;
          }
     
          else {
             printf("%s%s=%s\n", '   ' x $currentPad, $k, $v );
             $newDict->{$k} = $v;
          }
       }
    }
     
     
    _readDict(\%dict1, \%dict2);
    $Data::Dumper::Indent=1;
    print Data::Dumper->Dump( [\%dict2], ['dict2'] );
    Résultat
    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
     
    level1
       ---
       prp3=zzz
       prp2=bar
       prp1=foo1
       level2
          ---
          prp1=foo12
          prp2=bar12
          ---
          prp1=foo13
          prp2=bar13
       ---
       level2
          ---
          prp2=bar22
          prp1=foo22
          ---
          prp1=foo23
          prp2=bar23
       prp1=foo2
       prp2=bar
       prp3=zzz
    $dict2 = {
      'level1' => [
        {
          'prp3' => 'zzz',
          'prp1' => 'foo1',
          'prp2' => 'bar',
          'level2' => [
            {
              'prp2' => 'bar12',
              'prp1' => 'foo12'
            },
            {
              'prp2' => 'bar13',
              'prp1' => 'foo13'
            }
          ]
        },
        {
          'prp3' => 'zzz',
          'prp1' => 'foo2',
          'prp2' => 'bar',
          'level2' => [
            {
              'prp1' => 'foo22',
              'prp2' => 'bar22'
            },
            {
              'prp2' => 'bar23',
              'prp1' => 'foo23'
            }
          ]
        }
      ]
    };
    Comme déjà précisé, je ne souhaite pas copier un dictionnaire imbriqué (ou composite), mais bien alimenter un autre dictionnaire imbriqué.
    Si j'avais souhaité le copier, je ne vous aurais pas embêté...

    Je veux juste savoir comment je dois alimenter un composite vide en descendant et remontant dans sa hiérarchie, avec des pointeurs (ou l'équivalent).
    Un peu à la manière du Perl ci-dessus (qui n'utilise que des pointeurs (ou références)).

    Pour rappel, ce code est juste la simulation d'un Parser (Lex/Yacc) déjà écrit en Pthon, mais avec lequel je n'arrive pas à alimenter un composite vierge.

    Merci encore pour votre temps.

  13. #13
    Nouveau membre du Club Avatar de dca_marshall
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 46
    Points : 37
    Points
    37
    Par défaut
    Bah si ça marche en Perl, qu'ai-je donc fait avec Python pour que ça merdouille...

    Je suis donc reparti From Scratch sur le Python, en convertissant chaque bloc Perl.

    J'ai ai aussi ajouté qq éléments complémentaires pour voir.
    Donc voici ce que cela donne.

    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
     
    #!/usr/bin/env python3
    import json
     
    dict2 = {}
    currentPad = 0
     
    dict1 = {
       'level01': [
     
          {
             'prp1': 'foo1',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level11': [
                {
                   'prp1': 'foo12',
                   'prp2': 'bar12',
                },
                {
                   'prp1': 'foo13',
                   'prp2': 'bar13',
                },
             ],
          },
     
          {
             'prp1': 'foo2',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level12': [
                {
                   'prp1': 'foo22',
                   'prp2': 'bar22',
                },
                {
                   'prp1': 'foo23',
                   'prp2': 'bar23',
                },
             ],
          },
     
       ],
       'level02': [
     
          {
             'prp1': 'foo1',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level13': [
                {
                   'prp1': 'foo12',
                   'prp2': 'bar12',
                },
                {
                   'prp1': 'foo13',
                   'prp2': 'bar13',
                },
             ],
          },
     
          {
             'prp1': 'foo2',
             'prp2': 'bar',
             'prp3': 'zzz',
             'level14': [
                {
                   'prp1': 'foo22',
                   'prp2': 'bar22',
                },
                {
                   'prp1': 'foo23',
                   'prp2': 'bar23',
                },
             ],
          },
     
       ],
    }
     
     
    def _readList(myList, newDict):
       for myItem in myList:
          print("{}{}".format( '   ' * currentPad, '---'))
          newDict.append( {} )
          if isinstance(myItem, dict):
             _readDict( myItem, newDict[-1] )
     
     
     
     
    def _readDict(currentDict, newDict):
       global currentPad
       for k, v in currentDict.items():
          if isinstance(v, list):
             print("{}{}".format( '   ' * currentPad, k ))
             if not k in newDict:
                newDict[k] = []
             currentPad += 1
             _readList(v, newDict[k]);
             currentPad -= 1
     
          else:
             print("{}{}={}".format( '   ' * currentPad, k, v))
             newDict[k] = v
     
     
     
    _readDict(dict1, dict2)
    print('dict2' + json.dumps(dict2, indent=4, sort_keys=True))
    Et la sortie
    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
     
    level01
       ---
       prp1=foo1
       prp2=bar
       prp3=zzz
       level11
          ---
          prp1=foo12
          prp2=bar12
          ---
          prp1=foo13
          prp2=bar13
       ---
       prp1=foo2
       prp2=bar
       prp3=zzz
       level12
          ---
          prp1=foo22
          prp2=bar22
          ---
          prp1=foo23
          prp2=bar23
    level02
       ---
       prp1=foo1
       prp2=bar
       prp3=zzz
       level13
          ---
          prp1=foo12
          prp2=bar12
          ---
          prp1=foo13
          prp2=bar13
       ---
       prp1=foo2
       prp2=bar
       prp3=zzz
       level14
          ---
          prp1=foo22
          prp2=bar22
          ---
          prp1=foo23
          prp2=bar23
    dict2{
        "level01": [
            {
                "level11": [
                    {
                        "prp1": "foo12",
                        "prp2": "bar12"
                    },
                    {
                        "prp1": "foo13",
                        "prp2": "bar13"
                    }
                ],
                "prp1": "foo1",
                "prp2": "bar",
                "prp3": "zzz"
            },
            {
                "level12": [
                    {
                        "prp1": "foo22",
                        "prp2": "bar22"
                    },
                    {
                        "prp1": "foo23",
                        "prp2": "bar23"
                    }
                ],
                "prp1": "foo2",
                "prp2": "bar",
                "prp3": "zzz"
            }
        ],
        "level02": [
            {
                "level13": [
                    {
                        "prp1": "foo12",
                        "prp2": "bar12"
                    },
                    {
                        "prp1": "foo13",
                        "prp2": "bar13"
                    }
                ],
                "prp1": "foo1",
                "prp2": "bar",
                "prp3": "zzz"
            },
            {
                "level14": [
                    {
                        "prp1": "foo22",
                        "prp2": "bar22"
                    },
                    {
                        "prp1": "foo23",
                        "prp2": "bar23"
                    }
                ],
                "prp1": "foo2",
                "prp2": "bar",
                "prp3": "zzz"
            }
        ]
    }
    Donc cela fonctionne comme attendu.
    J'ai donc maintenant tous les éléments pour continuer mon Parser.

    MERCI infiniment de vos interventions

    De la discussion, jailli la lumière (Charles Monnard 1829)

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

Discussions similaires

  1. Création dynamique TADOConnection
    Par chaours dans le forum Bases de données
    Réponses: 6
    Dernier message: 19/04/2004, 10h54
  2. [D7] Création dynamique de Form
    Par jer64 dans le forum Composants VCL
    Réponses: 3
    Dernier message: 03/08/2003, 12h20
  3. [Rave Report] problème de création dynamique
    Par Nivux dans le forum Rave
    Réponses: 2
    Dernier message: 24/05/2003, 00h07
  4. TWebBrowser et création dynamique
    Par BakaOnigiri dans le forum Web & réseau
    Réponses: 2
    Dernier message: 01/09/2002, 10h53
  5. Création dynamique de TImages
    Par Dric dans le forum C++Builder
    Réponses: 10
    Dernier message: 08/07/2002, 12h36

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