如何在递归字典中搜索键的值?

3

我曾经写过一个递归函数来查找给定字典和键的值。 但我认为应该有更易读的版本。以下是代码块。

def findvalue(_dict, target):
    for key, values in _dict.items():
        if 'dict' in str(type(values)):
            return findvalue(values, target)
        elif key == target:
            return values
        else:
            print("no such key")

有没有一行代码或使用yield的版本实现这个功能?

编辑:根据递归函数和列表附加/扩展以及评论中的想法,我修改了函数以查找给定键的所有匹配值。

def find_all_value(_dict, target, values=None):
    for key, values in _dict.items():
        #case 1: it is a dictionary but not match the key
        if isinstance(values, dict) and key!=target:
            return find_all_value(values, target)
        #case 2: it is a dictionary but match the key -> put it in result
        elif isinstance(values, dict) and key==target:
            return [values] + find_all_value(values, target)
        #case 3: it is not dictionary and match the key -> put it in result
        elif key==target:
            return [values]

我认为你的代码不起作用。你正在在valuesstr(type())中搜索字面字符串值'dict'。所以你基本上是在做if 'dict' in '<class 'list'>',我相信这不是你想要的。 - Christian Dean
1
第一个“if”用于检查它是否为字典类型。 如果不是字典,则会检查key == target,如果为真,则返回值(可以是除字典以外的任何类型)。 - Poon King Sing
2个回答

2
为了找到一个递归Python字典中广度优先搜索所找到的第一个键(key)的值,你可以执行以下操作:
def find_value(_dict, key):
    stack = [(None, _dict)]
    while len(stack) != 0:
        _key, val = stack.pop(0)
        if val is not _dict and _key == key:
            return val
        if isinstance(val, dict):
            for k, v in val.items():
                stack.append((k, v))

例子:

d = {'c': {'d': 3, 'e': 4}, None: 0, 'b': 2, 'a': 1}

print('None:', find_value(d, None))
print('c:', find_value(d, 'c'))
print('e:', find_value(d, 'e'))
print('a:', find_value(d, 'a'))

输出:

None: 0
c: {'e': 4, 'd': 3}
e: 4
a: 1

这是一个更完整的版本,如果键是字典,它还可以处理返回值。 - Poon King Sing

0

##编辑:## 通过列表推导式递归搜索(嵌套)字典:

def findvalue(d, key):

    l = [e for e in [findvalue(e, key) for e in [d[k] for k in d.keys() if type(d[k])==dict]] if e]
    l.append(d[key]) if key in d else l
    return l

^ 返回每个匹配(嵌套)字典键的值列表(嵌套)。


简化版本,它打印而不是返回每个匹配项:

def findvalue(d, key):

    [findvalue(e, key) for e in [d[k] for k in d.keys() if type(d[k])==dict]]
    if key in d: print(d[key])

^ 只会在遇到每个匹配的键时显示其值。


使用以下代码进行测试:

d = {1:2, 3:4, 5:{6:7,8:9, 99:{100:101}}, 10:11}

这个看起来不错,但只能处理一层深度的情况。如果它可以检查嵌套字典,那就更好了。 - Poon King Sing
@PoonKingSing 更新:抱歉回复晚了。 - veganaiZe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接