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

dictionnaire de dictionnaire de ...

3 réponses
Avatar
Fouff
Bonjour à toutes et à tous.

Je me trouve confronté à un problème (sinon, je ne vous dérangerais pas ici ;-) ).
Voici :
-----------------------------------------------
def f1(fichier):
dict_of_infos_in_file = {"INFO_1" : "",
"INFO_2" : []
"INFO_3" : []}
...
dict_of_infos_in_file.__setitem__("INFO_1", "str")
...
dict_of_infos_in_file.__setitem__("INFO_2", [elem_1, elem_2, ...])
...
dict_of_infos_in_file.__setitem__("INFO_2", [elem_1, elem_2, ...])
...
...
return dict_of_infos_in_file


def f2(list_of_some_files):
dict_file = {}
...
for myFile in list_of_some_files :
res_dict = f1(myFile)
dict_file.__setitem__(myFile, res_dict)
...
return dict_file


dictionnaire = f2(liste_de_fichiers)
print dictionnaire
-----------------------------------------------
Et là ... c'est le drame !
J'ai globalement n'importe quoi dans les valeurs (retour de f1()) de dict_file (les clés sont bonnes
heureusement).

J'ai principalement des dictionnaires (ceux qui sont censés être rmplis par f1()) vides,
sauf des fois, 1 valeur est remplie mais elle n'appartient pas à ce dictionnaire ...

Bref, je ne comprend pas ce qui se passe !!!


J'ai donc essayé aussi :
dict_file.__setitem__(myFile, res_dict.copy())
Mais le résultat est ... comment dire ... identique au précédent !

D'avance MERCI de toute l'aide pertinente que vous pourrez me procurer.
Cordialement.

3 réponses

Avatar
Fouff
Fouff a écrit :
Bonjour à toutes et à tous.

Je me trouve confronté à un problème (sinon, je ne vous dérangerais pas
ici ;-) ).
Voici :
-----------------------------------------------
def f1(fichier):
dict_of_infos_in_file = {"INFO_1" : "",
"INFO_2" : []
"INFO_3" : []}
...
dict_of_infos_in_file.__setitem__("INFO_1", "str")
...
dict_of_infos_in_file.__setitem__("INFO_2", [elem_1, elem_2, ...])
...
dict_of_infos_in_file.__setitem__("INFO_2", [elem_1, elem_2, ...])
...
...
return dict_of_infos_in_file


def f2(list_of_some_files):
dict_file = {}
...
for myFile in list_of_some_files :
res_dict = f1(myFile)
dict_file.__setitem__(myFile, res_dict)
...
return dict_file


dictionnaire = f2(liste_de_fichiers)
print dictionnaire
-----------------------------------------------
Et là ... c'est le drame !
J'ai globalement n'importe quoi dans les valeurs (retour de f1()) de
dict_file (les clés sont bonnes heureusement).

J'ai principalement des dictionnaires (ceux qui sont censés être rmplis
par f1()) vides,
sauf des fois, 1 valeur est remplie mais elle n'appartient pas à ce
dictionnaire ...

Bref, je ne comprend pas ce qui se passe !!!


J'ai donc essayé aussi :
dict_file.__setitem__(myFile, res_dict.copy())
Mais le résultat est ... comment dire ... identique au précédent !

D'avance MERCI de toute l'aide pertinente que vous pourrez me procurer.
Cordialement.



Grrrrrrrr

Ayé j'ai trouvé.
Je me suis fait avoir en beauté avec les "shallow" copies de M(biiiiiiiiiiiiiiiip) !!!

-----------------------------------------------
def f1(fichier):
dict_of_infos_in_file = {"INFO_1" : "",
"INFO_2" : []
"INFO_3" : []}
...
dict_of_infos_in_file.__setitem__("INFO_1", "str")
dict_of_infos_in_file.__setitem__("INFO_2", [elem_1, elem_2, ...])
dict_of_infos_in_file.__setitem__("INFO_3", [elem_1, elem_2, ...])
...
return dict_of_infos_in_file

def fQuiFoutLeBronx(di):
...
dict_c = di.copy()
...
del dict_c["INFO_2"][0]
...
del dict_c

def f2(list_of_some_files):
dict_file = {}
...
for myFile in list_of_some_files :
res_dict = f1(myFile)
...
fQuiFoutLeBronx(res_dict)
...
dict_file.__setitem__(myFile, res_dict)
...
return dict_file


dictionnaire = f2(liste_de_fichiers)
print dictionnaire
-----------------------------------------------

Ca me fatigue d'avoir ce genre de choses qui ne me sont pas tellement familières.
Pour infos, la solution :
def fQuiFoutLeBronx(di):
import copy
...
# dict_c = di.copy()
dict_c = copy.deepcopy(di)
...
del dict_c["INFO_2"][0]
...
del dict_c

Et elle ne fiche plus le bazar !!! (donc éventuellement, on peut la renommer :D )

Par contre, je suis preneur si quelqu'un avait une explication/idée simple sur le pourquoi
du comment il est fait par défaut une copie des références des éléments, plutôt que directement
une copie "deep" des éléments.

MERCI pour les éventuelles réponses.
Cordialement.
Avatar
Bruno Desthuilliers
Fouff a écrit :
Bonjour à toutes et à tous.

Je me trouve confronté à un problème (sinon, je ne vous dérangerais pas
ici ;-) ).
Voici :
-----------------------------------------------
def f1(fichier):
dict_of_infos_in_file = {"INFO_1" : "",
"INFO_2" : []
"INFO_3" : []}
...
dict_of_infos_in_file.__setitem__("INFO_1", "str")



Normalement, la syntaxe est:

dict_of_infos_in_file["INFO_1"] = "str"


...
dict_of_infos_in_file.__setitem__("INFO_2", [elem_1, elem_2, ...])
...
dict_of_infos_in_file.__setitem__("INFO_2", [elem_1, elem_2, ...])
...
...
return dict_of_infos_in_file


def f2(list_of_some_files):
dict_file = {}
...
for myFile in list_of_some_files :
res_dict = f1(myFile)
dict_file.__setitem__(myFile, res_dict)



ou plus simplement:
dict_file=dict((fname, f1(fname)) for fname in list_of_some_files)

(NB : je suppose, of course, qu'il s'agit bien d'une liste de noms de
fichiers...)

...
return dict_file


dictionnaire = f2(liste_de_fichiers)
print dictionnaire



<hs>
Tu gagnerais probablement en lisibilité en revoyant et harmonisant un
peu le nommage de tes objets...
</hs>

Et là ... c'est le drame !
J'ai globalement n'importe quoi dans les valeurs (retour de f1()) de
dict_file (les clés sont bonnes heureusement).

J'ai principalement des dictionnaires (ceux qui sont censés être rmplis
par f1()) vides,
sauf des fois, 1 valeur est remplie mais elle n'appartient pas à ce
dictionnaire ...

Bref, je ne comprend pas ce qui se passe !!!


J'ai donc essayé aussi :
dict_file.__setitem__(myFile, res_dict.copy())
Mais le résultat est ... comment dire ... identique au précédent !



Pas de raison qu'il en soit autrement. La programmation par accident, ça
ne mène pas loin, en général...

D'avance MERCI de toute l'aide pertinente que vous pourrez me procurer.



Je ne vois pas très bien ce qu'on peut faire pour t'aider, vu que tu n'a
manifestement pas posté le code posant problème (ou au moins le code
minimum reproduisant le problème).

Pour ce que ça vaut, le code suivant fonctionne correctement:

def get_file_infos(filename):
return dict(
foo=filename,
bar=list(filename.upper()),
baaz=filename[::-1],
bak=len(filename)
)


def list_files_infos(filenames):
return dict((fname, get_file_infos(fname)) for fname in filenames)

results = list_files_infos(['toto', 'tatata', 'titititi'])
print results


=> {'titititi': {'baaz': 'itititit', 'foo': 'titititi', 'bar': ['T',
'I', 'T', 'I', 'T', 'I', 'T', 'I'], 'bak': 8}, 'tatata': {'baaz':
'atatat', 'foo': 'tatata', 'bar': ['T', 'A', 'T', 'A', 'T', 'A'], 'bak':
6}, 'toto': {'baaz': 'otot', 'foo': 'toto', 'bar': ['T', 'O', 'T', 'O'],
'bak': 4}}

Bref, le problème est manifestement dans le code que tu n'a *pas* posté.
Avatar
Bruno Desthuilliers
Fouff a écrit :
(snip)
Grrrrrrrr

Ayé j'ai trouvé.
Je me suis fait avoir en beauté avec les "shallow" copies de
M(biiiiiiiiiiiiiiiip) !!!



(snip)
Par contre, je suis preneur si quelqu'un avait une explication/idée
simple sur le pourquoi
du comment il est fait par défaut une copie des références des éléments,
plutôt que directement
une copie "deep" des éléments.



Parce que la shallow copy est 1/ ce qu'on veut dans environ 99% des cas
[*], et 2/ nettement moins coûteuse qu'une deep copy.

En général, dans le cas de figure illustré dans ton code, on préfère
construire une nouvelle liste (voire un nouveau dict) par filtrage de
l'original que de faire un deep copy puis des suppressions (nb : ce qui
ne veut pas dire que ta solution soit mauvaise ou injustifié - ça dépend
du cas d'utilisation, of course).

[*] et encore... De mémoire, je n'ai pas dû avoir l'usage de
copy.deepcopy plus d'une dizaine de fois en 8 ans...