对于单层dicts x = {'a': 1, 'b': 2},问题很容易,并在SO上回答(Pythonic方式检查两个字典是否有相同的键集?)但是嵌套dicts呢?
例如,y = {'a': {'c': 3}, 'b': {'d': 4}}有键'a','b'但我想将其形状与另一个嵌套的dict结构进行比较z = {'a': {'c': 5}, 'b': {'d': 6}},因为它具有相同的形状和键(不同的值很好)y.w = {'a': {'c': 3}, 'b': {'e': 4}}会有键'a','b'但在它的下一层不同,y因为w['b']有键'e'而y['b']有键'd'.
想的两个参数的短/简单的功能dict_1和dict_2并返回True,如果他们有,如上所述,以及相同的形状和键False除外.
这提供了两个被删除任何非字典值的字典的副本,然后比较它们:
def getshape(d):
if isinstance(d, dict):
return {k:getshape(d[k]) for k in d}
else:
# Replace all non-dict values with None.
return None
def shape_equal(d1, d2):
return getshape(d1) == getshape(d2)
Run Code Online (Sandbox Code Playgroud)
我喜欢nneonneo的答案,它应该相对较快,但我想要一些不会产生额外不必要的数据结构的东西(我一直在学习Python中的内存碎片).这可能会也可能不会更快或更快.
(编辑:剧透!)
通过足够好的余量使其在所有情况下都更可取,请参阅其他分析答案.
但是如果处理大量的这些并且存在内存问题,那么以这种方式进行操作可能更为可取.
这应该工作在Python 3,也许2.7如果你翻译keys到viewkeys,绝对不是2.6.它依赖于dicts具有的键的集合视图:
def sameshape(d1, d2):
if isinstance(d1, dict):
if isinstance(d2, dict):
# then we have shapes to check
return (d1.keys() == d2.keys() and
# so the keys are all the same
all(sameshape(d1[k], d2[k]) for k in d1.keys()))
# thus all values will be tested in the same way.
else:
return False # d1 is a dict, but d2 isn't
else:
return not isinstance(d2, dict) # if d2 is a dict, False, else True.
Run Code Online (Sandbox Code Playgroud)
编辑更新以减少冗余类型检查,现在更加高效.
去检查:
print('expect false:')
print(sameshape({'foo':{'bar':{None:None}}}, {'foo':{'bar':{None: {} }}}))
print('expect true:')
print(sameshape({'foo':{'bar':{None:None}}}, {'foo':{'bar':{None:'foo'}}}))
print('expect false:')
print(sameshape({'foo':{'bar':{None:None}}}, {'foo':{'bar':{None:None, 'baz':'foo'}}}))
Run Code Online (Sandbox Code Playgroud)
打印:
expect false:
False
expect true:
True
expect false:
False
Run Code Online (Sandbox Code Playgroud)