访问嵌套在字典中的值

Posted

技术标签:

【中文标题】访问嵌套在字典中的值【英文标题】:Accessing values nested within dictionaries 【发布时间】:2012-07-26 21:34:38 【问题描述】:

我有一本包含字典的字典,其中也可能包含字典,例如

dictionary = 'ID': 0001, 'Name': 'made up name', 'Transactions':
               'Transaction Ref': 'a1', 'Transaction Details':
                  'Bill To': 'abc', 'Ship To': 'def', 'Product': 'Widget A'
                      ... ... ... 

目前我正在拆包以获取 ID 001 的“Bill To”,“Transaction Ref”a1 如下:

if dictionary['ID'] == 001:
    transactions = dictionary['Transactions']
        if transactions['Transaction Ref'] == 'a1':
            transaction_details = transactions['Transaction Details']
            bill_to = transaction_details['Bill To']

我不禁觉得这有点笨拙,尤其是最后两行 - 我觉得以下几行应该可行:

bill_to = transactions['Transaction Details']['Bill To']

有没有一种更简单的方法可以深入到嵌套字典中,而不必解压到临时变量中?

【问题讨论】:

你认为应该有效的那条线确实有效。 请注意,0001 在 Python3 中无效,任何带前导零的数字也无效。 【参考方案1】:

你可以这样使用:

>>> def lookup(dic, key, *keys):
...     if keys:
...         return lookup(dic.get(key, ), *keys)
...     return dic.get(key)
...
>>> d = 'a':'b':'c':5
>>> print lookup(d, 'a', 'b', 'c')
5
>>> print lookup(d, 'a', 'c')
None

此外,如果您不想将搜索键定义为单独的参数,则可以将它们作为列表传递,如下所示:

>>> print lookup(d, *['a', 'b', 'c'])
5
>>> print lookup(d, *['a', 'c'])
None

【讨论】:

希望你不要介意,我添加了一个编辑来阐明这个功能真正的动态搜索能力。即时传递搜索键列表的能力使其优于其他技术。【参考方案2】:

以下是访问嵌套字典的另一种方式

>>> dbo='m':'d':'v':'version':1
>>> name='m__d__v__version' # it'll refer to 'dbo['m']['d']['v']['version']', '__' is the separator
>>> version = reduce(dict.get, name.split('__'), dbo)
>>> print version
1
>>>

这里,变量 'name' 指的是 'dbo['m']['d']['v']['version']',看起来更短更简洁。

此方法不会抛出 KeyError。如果未找到密钥,则您将得到“无”。

参考:http://code.activestate.com/recipes/475156-using-reduce-to-access-deeply-nested-dictionaries/

【讨论】:

如果你尝试 name='m__foo__v__foo',它会抛出一个 TypeError:TypeError: 描述符 'get' 需要一个 'dict' 对象但收到了一个 'NoneType'【参考方案3】:
bill_to = transactions['Transaction Details']['Bill To']

确实有效。 transactions['Transaction Details'] 是一个表示dict 的表达式,因此您可以在其中进行查找。不过,对于实际程序,我更喜欢嵌套字典的 OO 方法。 collections.namedtuple 对于快速设置一堆只包含数据(并且没有它们自己的行为)的类特别有用。

有一个警告:在某些设置中,您可能希望在查找时捕获 KeyError,而在此设置中,这也有效,很难判断哪个字典查找失败:

try:
    bill_to = transactions['Transaction Details']['Bill To']
except KeyError:
    # which of the two lookups failed?
    # we don't know unless we inspect the exception;
    # but it's easier to do the lookup and error handling in two steps

【讨论】:

以上是关于访问嵌套在字典中的值的主要内容,如果未能解决你的问题,请参考以下文章

在 VBA 中的字典值中查找最大值/最小值

Django模板访问嵌套数据

使用列表中的项目更改嵌套字典的字典中的值?

将字典嵌套在另一个字典中,按 Pandas Dataframe 中的值分组

用映射字典的值替换嵌套字典中的占位符

python - 如何在更改python中的值时合并一个嵌套字典和一个简单字典?