[Python] - dictionnaire et mise à jour d'entrée

- dictionnaire et mise à jour d'entrée [Python] - Python - Programmation

Marsh Posté le 14-11-2011 à 11:48:47    

Bonjour tout le monde,
 
Voici mon problème :  
 
J'ai un template de dictionnaire type

Code :
  1. asset = { "entrée1" : "blabla", "entrée2" : "plop",... ,"entréeN" : a,.... }

ensuite je parse
un dossier pour récupérer des identifiants et affecter ce template à un dictionnaire bcp plus gros (composé donc de pleins d'unité type  
asset) que j'enverrai par la suite dans un json. Voila le contexte.
Le souci ici réside dans l'affectation des différentes entrées. Je m'explique imaginons que j'ai un identifiant X avec un paramètre entréeN
à 3. Je procède comme suit,

Code :
  1. asset["entréeN"] = 3

puis je fais

Code :
  1. dictionnaireGlobal[X] = asset

puis je remets asset["entréeN"] à sa valeur  
initiale. Problème dictionnaireGlobal[X]["entréeN"] ne sera pas la valeur 3 mais à la valeur initiale o_O!!!! et bien sur si je ne remets pas
asset["entréeN"] à sa valeur initiale toutes les asset["entréeN"] qui apparaissent dans dictionnaireGlobal sont à 3!!
Au final je souhaiterai donc pouvoir modifier et sauvegarder des données suivant un template défini (sous forme d'un dictionnaire) sans que
cela n'affecte les précédentes sauvegardes. Je me comprends mais je ne sais pas si c'est suffisamment clair... Je flaire un problème de pointeur/valeur
mais si je ne m'abuse la notion de pointeur en python n'est pas trop répandue non?
Et la j'avoue mon ignorance, ou alors je suis passé à coté de qqc d'évident auquel cas je vous prie d'excuser le dérangement.
 
Merci d'avance pour votre aide,
 
R,

Message cité 1 fois
Message édité par luclechanceux le 14-11-2011 à 14:16:06
Reply

Marsh Posté le 14-11-2011 à 11:48:47   

Reply

Marsh Posté le 14-11-2011 à 14:36:47    

A priori il faut importer le module copy et procéder comme suit :  

Code :
  1. template = {"cle":"valeur1"}
  2. dicGlobal["X"] = coppy.copy(template)
  3. template["cle"] = "valeur2"
  4. dicGlobal["Y"] = coppy.copy(template)


 
on aura bien :  

Code :
  1. dicGlobal["X"]["cle"] = "valeur1"
  2. dicGlobal["Y"]["cle"] = "valeur2"


 
et non :

Code :
  1. dicGlobal["X"]["cle"] = "valeur2"
  2. dicGlobal["Y"]["cle"] = "valeur2"


 
comme c'était le cas sans le module...
 
Merci,
 
R,
 

Reply

Marsh Posté le 19-11-2011 à 15:04:38    

luclechanceux a écrit :

Bonjour tout le monde,
 
Voici mon problème :  
 
J'ai un template de dictionnaire type

Code :
  1. asset = { "entrée1" : "blabla", "entrée2" : "plop",... ,"entréeN" : a,.... }

ensuite je parse
un dossier pour récupérer des identifiants et affecter ce template à un dictionnaire bcp plus gros (composé donc de pleins d'unité type  
asset) que j'enverrai par la suite dans un json. Voila le contexte.
Le souci ici réside dans l'affectation des différentes entrées. Je m'explique imaginons que j'ai un identifiant X avec un paramètre entréeN
à 3. Je procède comme suit,

Code :
  1. asset["entréeN"] = 3

puis je fais

Code :
  1. dictionnaireGlobal[X] = asset

puis je remets asset["entréeN"] à sa valeur  
initiale. Problème dictionnaireGlobal[X]["entréeN"] ne sera pas la valeur 3 mais à la valeur initiale o_O!!!! et bien sur si je ne remets pas
asset["entréeN"] à sa valeur initiale toutes les asset["entréeN"] qui apparaissent dans dictionnaireGlobal sont à 3!!
Au final je souhaiterai donc pouvoir modifier et sauvegarder des données suivant un template défini (sous forme d'un dictionnaire) sans que
cela n'affecte les précédentes sauvegardes. Je me comprends mais je ne sais pas si c'est suffisamment clair... Je flaire un problème de pointeur/valeur
mais si je ne m'abuse la notion de pointeur en python n'est pas trop répandue non?
Et la j'avoue mon ignorance, ou alors je suis passé à coté de qqc d'évident auquel cas je vous prie d'excuser le dérangement.


 
Salut
 
Les pointeurs en Python sont très répandus... mais aussi très cachés. Toutefois, toute copie d'objet un tant soi peu complexe ne se fait que par pointeur
 
Exemple

Code :
  1. >>> a=range(5)
  2. >>> a
  3. [0, 1, 2, 3, 4]
  4. >>> b=a
  5. >>> a[0]="toto"
  6. >>> b
  7. ['toto', 1, 2, 3, 4]


 
Alors tu as bien trouvé le truc => passer par le module "copy" qui copie les objets par contenu et non par pointeur. Cependant, la méthode copy.copy s'arrête au premier niveau et le problème persiste si les objets copiés possèdent eux-mêmes des objets complexes
 
Exemple

Code :
  1. >>> import copy
  2. >>> a={"key1" : 10, "key2" : {"base" : range(5)}}
  3. >>> b=copy.copy(a)
  4. >>> a
  5. {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10}
  6. >>> b
  7. {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10}
  8. >>> a["key1"]=5
  9. >>> a
  10. {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 5}
  11. >>> b
  12. {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10}
  13. >>> a["key2"]["base"]="toto"
  14. >>> a
  15. {'key2': {'base': 'toto'}, 'key1': 5}
  16. >>> b
  17. {'key2': {'base': 'toto'}, 'key1': 10}


 
Comme tu le vois, la copie s'est arrêtée au premier niveau "key1". Le second objet "key2" a été, lui, copié par adresse.
 
Si tu veux une copie vraiment séparée quelle que soit la profondeur des objets imbriqués, il te faut utiliser "copy.deepcopy"
 

Code :
  1. >>> a={"key1" : 10, "key2" : {"base" : range(5)}}
  2. >>> a
  3. {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10}
  4. >>> b=copy.deepcopy(a)
  5. >>> b
  6. {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10}
  7. >>> a["key1"]=5
  8. >>> a["key2"]["base"]="toto"
  9. >>> a
  10. {'key2': {'base': 'toto'}, 'key1': 5}
  11. >>> b
  12. {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10}


Message édité par Sve@r le 19-11-2011 à 15:06:33
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed