Python 从嵌套字典获取

Python 从嵌套字典获取,python,dictionary,Python,Dictionary,从Python字典中获取密钥或none的方法有很多种,但问题是我似乎找不到一种有效的方法来处理嵌套字典,也就是说,我需要my_dict['author']['email'],因为链接.get()两次都会命中非类型。 我想扩展字典.get(),以便能够链接嵌套的dict,即.get(['author']['email'])——但这意味着我必须将所有内容重新初始化为自定义字典类型(我想) 具体的情况是,我有两个模式,通过这两个模式,数据存储在Mongodb中,以便进行一个小的转换,我正在尝试找到获取

从Python字典中获取密钥或
none
的方法有很多种,但问题是我似乎找不到一种有效的方法来处理嵌套字典,也就是说,我需要
my_dict['author']['email']
,因为链接
.get()
两次都会命中非类型。 我想扩展字典
.get()
,以便能够链接嵌套的dict,即
.get(['author']['email'])
——但这意味着我必须将所有内容重新初始化为自定义字典类型(我想)

具体的情况是,我有两个模式,通过这两个模式,数据存储在Mongodb中,以便进行一个小的转换,我正在尝试找到获取正确信息的最佳方法。(存储前的所有数据都验证为两个模式之一)

因此,例如,对于非嵌套项,在模式中以不同的方式存储,可以执行以下操作:

#get database_info
author_name = database_info['author'] if database_info.get('author') else database_info['author_name'] 

但是对于
数据库信息['author']['email']
(其中author是包含其他键、值的字典对象),必须执行以下操作:

try: author_email = database_info['author']['email']
except: database_info['contributor']['email_address']
有没有一个最佳的方式来实现这一点?我认为攻击它的一种方式是这样的(对于嵌套字典的任意路径):


这里有一个通用的解决方案:

#!/usr/bin/env python


from __future__ import print_function


def select(d, *keys, **options):
    try:
        for key in keys:
            d = d[key]
        return d
    except:
        if "default" in options:
            return options["default"]
        raise


d = {
    "foo": {
        "bar": {
            "baz": 1
        }
    }
}


print(select(d, "foo", "bar", "baz"))
输出:

$ python foo.py 
1
其他一些用法:

$python-i foo.py
1.
>>>选择(d,“foobar”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“foo.py”,第10行,选择
d=d[键]
KeyError:“foobar”
>>>选择(d,“foobar”,default=“未找到”)
“未找到”
>>> 
灵感来自于我自己对等价函数的理解。

简单的例子是

author_name = database_info.get('author') or database_info['author_name'] 
两个折叠的箱子

author_email = database_info.get('author', {}).get('email') or database_info['contributor']['email_address']

如果您发布了dict结构的示例,可能会有所帮助。在执行访问之前,您可以确定模式吗?如果是这样的话,那么你可以在两个直接执行访问的函数之间进行选择。我可以,但我实际上认为代码比为两个不同的模式使用两个单独的函数更简洁,因为很多模式都是相同的。当然,如果valite(item_data,schema1),我可以直接做:elif validate(item_data,schema2)为什么人们不赞成这个,似乎以有效的方式获取嵌套dict值或无嵌套dict值的最佳方法是一个非常合理的问题?编写一个函数
nested_get(root_dict,*vargs,default=None)
它包含您想要的多个dict级别所需的功能。这将保持它的整洁,不会把你的整体功能搞得一团糟。
$ python -i foo.py 
1
>>> select(d, "foobar")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "foo.py", line 10, in select
    d = d[key]
KeyError: 'foobar'
>>> select(d, "foobar", default="Not Found")
'Not Found'
>>> 
author_name = database_info.get('author') or database_info['author_name'] 
author_email = database_info.get('author', {}).get('email') or database_info['contributor']['email_address']