我有一个深层嵌套的对象,其中包含各种列表和命令,它们作为json检索,需要与自身的另一个版本进行比较。问题是所有列表基本上都未排序,因此在比较它们之前我需要进行排序。如果没有正确排序列表中的字典位置,我尝试过的任何深层差异库都会失败,所以我们开始吧。
需要排序的样本对象:
{
"main":{
"key1":"value1",
"key2":"value2",
"key3":[{
"sub1":"value2",
"sub2":{
"subsub":[{
"subsubsub1":10,
"subsubsub2":11,
"subsubsub3":[10,11,12]
},{
"subsubsub1":7,
"subsubsub2":8,
"subsubsub3":[9,7,8]
}]
}
},{
"sub1":"value1",
"sub2":{
"subsub":[{
"subsubsub1":1,
"subsubsub2":2,
"subsubsub3":[1,2,3]
},
{
"subsubsub1":4,
"subsubsub2":5,
"subsubsub3":[5,6,4]
}]
}
}]
}
}
除了一些递归循环外,我还尝试通过将字典与排序后的列表转换为排序后的元组并对其进行哈希处理来对字典进行排序。
编辑: 该对象传递到unnest()
def unnest(d):
for k, v in d.items():
if isinstance(v, dict):
d.update({k: unnest(v)})
elif isinstance(v, list):
d.update({k: unsort(v)})
return d
def unsort(l):
for i, e in enumerate(l):
if isinstance(e, dict):
l[i] = unnest(e)
elif isinstance(e, list):
l[i] = unsort(e)
return sorted(l, key=lambda i: sort_hash(i))
def unnest_hash(d):
for k, v in d.items():
if isinstance(v, dict):
d.update({k: unnest_hash(v)})
elif isinstance(v, list):
d.update({k: sort_hash(v)})
return hash(tuple(sorted(d.items())))
def sort_hash(l):
if isinstance(l, list):
for i, e in enumerate(l):
if isinstance(e, dict):
l[i] = unnest_hash(e)
elif isinstance(e, list):
l[i] = sort_hash(e)
return hash(tuple(sorted(l)))
elif isinstance(l, dict):
return unnest_hash(l)
else:
return hash(l)
但是由于某种原因,哈希值被写入“已排序”列表:
{'main': {'key1': 'value1', 'key2': 'value2', 'key3': [{'sub1': 'value2', 'sub2': -4046234112924644199}, {'sub1': 'value1', 'sub2': 4015568797712784641}]}}
如何防止lambda函数中的排序值写入返回的排序列表中? 谢谢!
答案 0 :(得分:1)
您的sort_hash
函数正在变异传递给它的值。这就是为什么您在原始值中看到它的原因:
l[i] = unnest_hash(e)
和
l[i] = sort_hash(e)
都修改您要哈希的值。 unnest_hash
还会修改原始值:
d.update({k: unnest_hash(v)})
用于排序的哈希计算必须永远不要修改其哈希值。