如何以最有效的方式在嵌套字典中获取指定的键值?

时间:2019-04-12 12:32:44

标签: python dictionary

有一个类似的嵌套字典:

data_dict = {
 "picture":"xxx.jpg",
 "link_data":{
     "picture":"xxxxx.jpg", 
     ... 
     "child_attachments":{
            "picture":"xxxxx.jpg", 
              ... 
       }
  }
  ...
}

问题出在字典的每个级别,键picture可能存在,如何以最有效的方式获得图片的价值?

这是我的审判,但未成功:

def get_picture_url(data):
    for key, value in data.items():
        if key == "picture":
            return data[key]
        else:
            if isinstance(value, dict):
                return get_picture_url(value)

get_picture_url(data_dict)

2 个答案:

答案 0 :(得分:0)

您没有检查对get_picture_url的递归调用的返回值。

这应该给您字典中最重要的图片:

def get_picture_url(data, picture_key="picture"):
    if not isinstance(data, dict):
        return None
    picture_url = data.get(picture_key)
    if picture_url is not None:
        return picture_url
    for value in data.values():
        picture_url = get_picture_url(value)
        if picture_url is not None:
            return picture_url
    return None

答案 1 :(得分:0)

这应该适用于具有JSON类结构的任意嵌套字典的一般情况:

def get_picture(data):
    # you can remove this case if the
    # input doesn't contain lists
    if isinstance(data, list):
        ans = []
        for e in data:
            ans += get_picture(e)
        return ans
    elif not isinstance(data, dict):
        return []
    else:
        ans = []
        for k, v in data.items():
            if k == 'picture':
                ans.append(v)
            else:
                ans += get_picture(v)
        return ans

它将遍历数据结构的所有级别,查找名为'picture'的键并将它们的所有值累加到一个输出列表中。如果您确定输入中没有列表,我们可以稍微简化一下解决方案:

def get_picture(data):
    ans = []
    if isinstance(data, dict):
        for k, v in data.items():
            if k == 'picture':
                ans.append(v)
            else:
                ans += get_picture(v)
    return ans

无论哪种方式,它都能为您的示例输入提供预期的效果:

data_dict = {
 "picture":"xxx.jpg",
 "link_data":{
    "picture":"xxxx.jpg",
    "child_attachments":{
        "picture":"xxxxx.jpg"
    }
  }
}

get_picture(data_dict)
=> ['xxx.jpg', 'xxxx.jpg', 'xxxxx.jpg']