在python中的dicts树中搜索值

时间:2013-04-29 20:35:50

标签: python algorithm search dictionary tree

我有一个巨大的词典,里面有很多嵌套的词汇 - 就像一棵巨树,深度未知。

我需要一个像find_value()这样的函数,它接受 dict,value(作为字符串),并返回列表列表,每个函数都有一个是“路径”(从第一个键到键的顺序链键(或键值)和找到的值)。如果找不到任何内容,则返回空列表。

我写了这段代码:

def find_value(dict, sought_value, current_path, result):   
    for key,value in dict.items():
        current_path.pop()
        current_path.append(key)
        if sought_value in key:
            result.append(current_path)
        if type(value) == type(''):
            if sought_value in value:
                result.append(current_path+[value])
        else:
            current_path.append(key) 
            result = find_value(value, sought_value, current_path, result)
    current_path.pop()
    return result 

我将此功能称为测试:

result = find_value(self.dump, sought_value, ['START_KEY_FOR_DELETE'], [])
if not len(result):
    print "forgive me, mylord, i'm afraid we didn't find him.."
elif len(result) == 1:
    print "bless gods, for all that we have one match, mylord!"

由于一些莫名其妙的原因,我的一些测试失败了。我开始调试并发现,即使 current_path 打印出正确的东西(它总是这样,我检查了!),结果也莫名其妙地被破坏了。也许是因为递归魔术?

任何人都可以帮我解决这个问题吗?也许我的任务有一个简单的解决方案?

2 个答案:

答案 0 :(得分:2)

当你写result.append(current_path)时,你不是在复制current_path,而是继续变异。将其更改为result.append(current_path[:])

答案 1 :(得分:1)

我怀疑你能做多少优化这样的递归搜索。假设在同一个字典上有很多查找,并且字典在加载后不会更改,那么您可以将其编入索引以获得O(1)查找...

def build_index(src, dest, path=[]):
    for k, v in src.iteritems():
        fk = path+[k]
        if isinstance(v, dict):
            build_index(v, dest, fk)
        else:
            try:
                dest[v].append(fk)
            except KeyError:
                dest[v] = [fk]

>>> data = {'foo': {'sub1': 'blah'}, 'bar': {'sub2': 'whatever'}, 'baz': 'blah'}
>>> index = {}
>>> build_index(data, index)
>>> index
{'blah': [['baz'], ['foo', 'sub1']], 'whatever': [['bar', 'sub2']]}
>>> index['blah']
[['baz'], ['foo', 'sub1']]