Même solution que celle acceptée, mais avec un nom de variable plus clair, une docstring, et la correction d'un bug où {}
en tant que valeur ne serait pas remplacée.
import collections
def deep_update(source, overrides):
"""
Update a nested dictionary or similar mapping.
Modify ``source`` in place.
"""
for key, value in overrides.iteritems():
if isinstance(value, collections.Mapping) and value:
returned = deep_update(source.get(key, {}), value)
source[key] = returned
else:
source[key] = overrides[key]
return source
Voici quelques cas de test :
def test_deep_update():
source = {'hello1': 1}
overrides = {'hello2': 2}
deep_update(source, overrides)
assert source == {'hello1': 1, 'hello2': 2}
source = {'hello': 'to_override'}
overrides = {'hello': 'over'}
deep_update(source, overrides)
assert source == {'hello': 'over'}
source = {'hello': {'value': 'to_override', 'no_change': 1}}
overrides = {'hello': {'value': 'over'}}
deep_update(source, overrides)
assert source == {'hello': {'value': 'over', 'no_change': 1}}
source = {'hello': {'value': 'to_override', 'no_change': 1}}
overrides = {'hello': {'value': {}}}
deep_update(source, overrides)
assert source == {'hello': {'value': {}, 'no_change': 1}}
source = {'hello': {'value': {}, 'no_change': 1}}
overrides = {'hello': {'value': 2}}
deep_update(source, overrides)
assert source == {'hello': {'value': 2, 'no_change': 1}}
Cette fonction est disponible dans le charlatan paquet, en charlatan.utils
.
0 votes
L'imbrication est-elle toujours de trois niveaux de profondeur ou peut-on avoir une imbrication d'une profondeur arbitraire ?
1 votes
Il peut avoir n'importe quelle profondeur/longueur.
0 votes
Corrigez-moi si je me trompe, mais il semble que la solution idéale ici nécessite la mise en œuvre du modèle de conception composite.