查找包含列表

时间:2016-06-22 02:04:48

标签: python dictionary

我想提取两个嵌套字典之间的差异,我希望结果包含完整的字典键路径。我已经安装了Python2.7和DeepDiff,这似乎是我想要实现的最佳选择。我试图确定如何更改DeepDiff的输出,以便它提供完整的字典路径和值,而不是我无法索引的集合。有没有更好的方法来改变输出(而不是将输出转换回字典)?

代码:

from __future__ import print_function
from deepdiff import DeepDiff
knownAPs = {'WLC1': {'10.1.1.1': {'72.6': ['AP22', 'city'], '55.1': ['AP102', 'office']}}, 'WLC2': {'10.1.1.2': {}}}
discoveredAPs = {'WLC1': {'10.1.1.1': {}}, 'WLC2': {'10.1.1.2': {}}}
ddiff = DeepDiff(knownAPs, discoveredAPs)
if 'dic_item_added' in ddiff.keys():
    print('Item added to known: ' + str((ddiff['dic_item_added'])))
if 'dic_item_removed' in ddiff.keys():
    DisAssociatedAPs = (list(list(ddiff['dic_item_removed'])))
    for i in DisAssociatedAPs:
        fullkeypath = (str(i).strip('root'))
        ControllerName = (fullkeypath[0])
        ControllerIP = (fullkeypath[1])
        AccessPointIndex = (fullkeypath[2])
        print('AP: ' + str(knownAPs + fullkeypath) + ' on controller: ' + str(ControllerName) + ' was removed from the known database')
if 'values_changed' in ddiff.keys():
    print('Item changed: ' + str((ddiff['values_changed'])))

输出

Traceback (most recent call last):
  File "C:/xxx/testdic4.py", line 15, in <module>
    print('AP: ' + str(knownAPs + fullkeypath) + ' on controller: ' + str(ControllerName) + ' was removed from the known database')
TypeError: unsupported operand type(s) for +: 'dict' and 'str'

Process finished with exit code 1

首选输出

AP: ['AP22', 'city'] on controller: ['WLC1'] was removed from the known database
AP: ['AP102', 'office'] on controller: ['WLC1'] was removed from the known database

1 个答案:

答案 0 :(得分:1)

问题正是回溯告诉你的:你正在尝试将字典添加到字符串中,这当然不是你想要的。具体来说,当您将knownAPs(类型dict)添加到fullkeypath(类型str)时会出现错误,因为dict不知道如何添加本身为str

但这并没有回答你如何以你想要的方式输出差异的更普遍的问题。试试这个:

diffs = deepdiff.DeepDiff(knownAPs, discoveredAPs)

def get_value_from_string(d, s):
    s = list(filter(None, (piece[2:-1] for piece in s.split(']'))))

    for piece in s:
        d = d[piece]
    return d


if 'dic_item_removed' in diffs:
    for item in diffs['dic_item_removed']:
        item = item.strip('root')
        base = item[2:item.find(']') - 1]
        print('AP:', get_value_from_string(knownAPs, item), 
            'on controller: \'' + base + '\' was removed from the known '
            'database')