I have a few dictionaries that are nested like this, the goal is to replace one dictionary without removing its other nested dictionaries.
Yo ---> soy ---> Lola ---> que ---> tal
\---> Maria --> hola
The function that we will see below works very well in part, it replaces Lola with Carlos
Yo ---> soy ---> Carlos--> que ---> tal
\---> Maria --> hola
Leaving intact the sub dictionaries that were in Lola however here comes the problem. If you try to replace the dictionary or Key (Yo) the entire dictionary is deleted, obviously including the sub-dictionaries, leaving everything empty.
This is the function that replaces a dictionary
def aprender_con_reemplazo(oracion, buscar):
recordar_pal = sobre_ti
for palabra in oracion.split():
if buscar in recordar_pal:
recordar_pal[palabra] = recordar_pal[buscar] # <--- Añadido esto
del recordar_pal[buscar]
if palabra not in recordar_pal:
recordar_pal[palabra] = {}
recordar_pal = recordar_pal[palabra]
demonstration:
sobre_ti={}
aprender("Yo soy Lola que tal")
aprender("Yo soy Maria hola")
aprender_con_reemplazo("Yo soy Carlos", "Lola")
print(sobre_ti)
Resultado:
{'Yo': {'soy': {'Maria': {'hola': {}},
'Carlos': {'que': {'tal': {}}}}}
}
Try replacing (Yo)
the real problem
The problem occurs in this case not because the word is the first in the tree, but because the word you want to replace ("I") matches the word you are going to put in its place (also "I").
Look at an example where this is not the case, and it works fine:
Result:
You can see how in this case the "I" at the top of the tree has been replaced by "Here", and the rest of the tree has been preserved. In addition, a new branch has been added below "Here", with "I am".
The problem, as I indicated, is not with the root of the tree but with the fact that the word you are trying to change matches the new one. For example, the same would happen in any other branch of the tree if you want to change "Lola" to "Lola". The rest of that branch would be lost. Look:
Comes out:
Why is this happening?
Because of the next couple of lines after the
if
:When
"Lola"
it finds a level in the tree, theif
. So it logs in and the first thing it does is copy the old branch under "Lola" into a new entry. When that entry was "Carlos", everything went well, because a new entry is created and then the "Lola" entry is deleted with thedel
. But whenpalabra
it is equal tobuscar
the line that tries to create a new entry, it doesn't actually create anything new, since that entry already existed. In this case it will simply dorecordar_pal["Lola"] = recordar_pal["Lola"]
. And because afterdel recordar_pal["Lola"]
that branch is made, it is deleted.That was the bug.
Solution
Actually when the word to replace matches the substitute word, nothing should be done, but add the rest of the sentence as a new branch under that word. That's what the function did anyway
aprender()
. Therefore, it is enough to improve the condition ofif
to prevent it from making the "substitution" if the two words are the same.tests
The following tests show that everything is working fine now (I hope!)
Produces:
And it also works with the root of the tree:
Result: