Como parece que nadie mencionó deepdiff
, lo agregaré aquí para completar. Me resulta muy conveniente para obtener diff de objetos (anidados) en general:
Instalación
pip install deepdiff
Código de muestra
import deepdiff
import json
dict_1 = {
"a": 1,
"nested": {
"b": 1,
}
}
dict_2 = {
"a": 2,
"nested": {
"b": 2,
}
}
diff = deepdiff.DeepDiff(dict_1, dict_2)
print(json.dumps(diff, indent=4))
Salida
{
"values_changed": {
"root['a']": {
"new_value": 2,
"old_value": 1
},
"root['nested']['b']": {
"new_value": 2,
"old_value": 1
}
}
}
Nota sobre la impresión bonita del resultado para la inspección: el código anterior funciona si ambos dictos tienen las mismas claves de atributo (posiblemente con valores de atributo diferentes como en el ejemplo). Sin embargo, si un "extra"
atributo está presente es uno de los dictados, json.dumps()
falla con
TypeError: Object of type PrettyOrderedSet is not JSON serializable
Solución: use diff.to_json()
y json.loads()
/ json.dumps()
para imprimir bonito:
import deepdiff
import json
dict_1 = {
"a": 1,
"nested": {
"b": 1,
},
"extra": 3
}
dict_2 = {
"a": 2,
"nested": {
"b": 2,
}
}
diff = deepdiff.DeepDiff(dict_1, dict_2)
print(json.dumps(json.loads(diff.to_json()), indent=4))
Salida:
{
"dictionary_item_removed": [
"root['extra']"
],
"values_changed": {
"root['a']": {
"new_value": 2,
"old_value": 1
},
"root['nested']['b']": {
"new_value": 2,
"old_value": 1
}
}
}
Alternativa: uso pprint
, resultados en un formato diferente:
import pprint
# same code as above
pprint.pprint(diff, indent=4)
Salida:
{ 'dictionary_item_removed': [root['extra']],
'values_changed': { "root['a']": { 'new_value': 2,
'old_value': 1},
"root['nested']['b']": { 'new_value': 2,
'old_value': 1}}}
x == y
debe ser cierto de acuerdo con stackoverflow.com/a/5635309/186202