Python 比较一个嵌套字典在另一个嵌套字典中的键和值

Python 比较一个嵌套字典在另一个嵌套字典中的键和值,python,python-3.x,python-2.7,dictionary,nested-loops,Python,Python 3.x,Python 2.7,Dictionary,Nested Loops,我尝试递归地比较以下两个python字典: expectededr = {'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'attempted': {'smpp': {'registeredDelivery': 0}, 'status': 'success', 'OATON': 1, 'OANPI': 1, 'DATON': 1, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404'}, 'custo

我尝试递归地比较以下两个python字典:

expectededr = {'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'attempted': {'smpp': {'registeredDelivery': 0}, 'status': 'success', 'OATON': 1, 'OANPI': 1, 'DATON': 1, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404'}, 'customerID': 'customer01', 'productID': 'product'}

edr = {'Category': 'NO', 'Type': 'mt', 'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'protocolID': 'smpp', 'direction': 'attempted', 'attempted': {'status': 'success', 'OANPI': 1, 'DATON': 1, 't2': 1512549691602, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404', 'smpp': {'fragmented': False, 'sequenceID': 1, 'registeredDelivery': 0, 'messageID': '4e7b48ad-b39e-4e91-a7bb-2de463e4a6ee', 'srcPort': 39417, 'messageType': 4, 'Status': 0, 'ESMClass': 0, 'dstPort': 0, 'size': 0}, 'OATON': 1, 'PID': 0, 't1': 1512549691602}, 'customerID': 'customer01', 'productID': 'product'}  
我试图以一种方式比较,在第二个字典中查找并比较第一个字典的键和值,如果匹配,则
print PASS
else
print FAIL

for key in expectededr:
   if expectededr[key] == edr[key]:
       print("PASS")
   else:
       print("FAIL")
输出:

FAIL
PASS
PASS
PASS
customer01
customer01
e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3
e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3
product
product
上述代码无法比较所有键和值,因为它们是嵌套字典。
正如您在下面看到的,如果我打印上面的键和值,我会发现它不会进入子字典,并且会丢失它们的键:

for key in expectededr:
    if expectededr[key] == edr[key]:
        print(expectededr[key])
        print(edr[key])
输出:

FAIL
PASS
PASS
PASS
customer01
customer01
e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3
e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3
product
product

有人能帮我更新这段代码,这样我就可以在这些嵌套字典中进行比较了吗?

一种方法是将字典展平,然后比较键是否匹配

因此,让我们先初始化你的口述:

In [23]: expectededr = {'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'attempted': {'smpp': {'registeredDelivery': 0}, 'status': 'success', 'OATON': 1, 'OANP
    ...: I': 1, 'DATON': 1, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404'}, 'customerID': 'customer01', 'productID': 'product'}
    ...: 
    ...: edr = {'Category': 'NO', 'Type': 'mt', 'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'protocolID': 'smpp', 'direction': 'attempted', 'attempted': {'
    ...: status': 'success', 'OANPI': 1, 'DATON': 1, 't2': 1512549691602, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404', 'smpp': {'fragmented': False, '
    ...: sequenceID': 1, 'registeredDelivery': 0, 'messageID': '4e7b48ad-b39e-4e91-a7bb-2de463e4a6ee', 'srcPort': 39417, 'messageType': 4, 'Status': 0, 'ESMCl
    ...: ass': 0, 'dstPort': 0, 'size': 0}, 'OATON': 1, 'PID': 0, 't1': 1512549691602}, 'customerID': 'customer01', 'productID': 'product'}  
    ...: 
为了使您的词典更平坦,我们可以使用:

并生成扁平的dicts

In [25]: flat_expectededr = flatten(expectededr)

In [26]: flat_edr = flatten(edr)
现在是一个简单的比较:

In [27]: for key in flat_expectededr:
    ...:     if flat_edr.get(key) == flat_expectededr[key]:
    ...:         print "PASS"
    ...:     else:
    ...:         print "FAIL"
PASS
PASS
PASS
PASS
PASS
PASS
PASS
PASS
PASS
PASS
PASS
简单方法:

for i in edr.keys():
    if i in expectededr.keys():
        print 'true : key'+i
    else:
        print 'fail : key'+ i

你的第一行研究不是谷歌“Python比较嵌套字典”吗?我做了,上面的链接不是解决我问题的答案或线索。谢谢,我不敢苟同。另一个q打印出任何不同的键。在这种情况下,您只需要打印“FAIL”并退出。它仍然不会检查和比较子字典{'smpp':{'registereddedelivery':0},'status':'succes','OATON':1,'OANPI':1,'DATON':1,'DANPI':1,'OA':'12149921220','DA':'1514525404}的kyes例如,两个词典都有“状态”:“成功”,但它没有使用上述代码比较此键值。@UjjawalKhare检查我的答案,让我知道这是否对您有效。@mu:请使用此词典检查我的评论,它没有比较“状态”:“成功”,它位于“尝试”中:{smpp':{registeredDelivery':0}我明白了,@UjjawalKhare,“‘状态’:‘成功’,‘OATON’:1,‘OANP…:I’:1,‘DATON’:1,‘DANPI’:1,‘OA’:‘12149921220’,‘DA’:‘1514525404’}。是否保证同一密钥在任何嵌套级别中只存在一次?如果是这种情况,在上面的函数展平中,您可以使用
new\u key=k
替换
new\u key=parent\u key+sep+k(如果parent\u key else k
)。然而,如果键可以重复,那么您就不能以自动方式进行比较,因为一个键可以告诉您它匹配,而另一个键可能不匹配。FWIW,字典中已经有2个状态和状态键。我尝试了你的建议,这正是我想要它工作的方式。我只想知道一件事。。。有没有办法打印出哪个元素的打印失败?我们是否可以限制如此多的通过和失败,并将其限制为即使一个键值匹配失败,我们也可以只打印不匹配的键值和值,然后打印失败?@UjjawalKhare您可以在else部分使用
break
语句,或者甚至可以沿边通过或失败打印键。如果你还有疑问,问一个新问题。