简体   繁体   English

访问嵌套在词典中的值

[英]Accessing values nested within dictionaries

I have a dictionary which contains dictionaries, which may also contain dictionaries, eg 我有一个字典,其中包含字典,也可能包含字典,例如

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

Currently I'm unpacking to get the 'Bill To' for ID 001, 'Transaction Ref' a1 as follows: 目前我打开包装以获取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']

I can't help but think this is is a little clunky, especially the last two lines - I feel like something along the lines of the following should work: 我不禁想到这是一个有点笨重,特别是最后两行 - 我觉得下面的内容应该有效:

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

Is there a simpler approach for drilling down into nested dictionaries without having to unpack into interim variables? 是否有更简单的方法可以深入到嵌套字典而无需解压缩到临时变量?

You can use something like this: 你可以使用这样的东西:

>>> 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

Additionally, if you don't want to define your search keys as individual parameters, you can just pass them in as a list like this: 此外,如果您不想将搜索键定义为单个参数,则可以将它们作为列表传递,如下所示:

>>> print lookup(d, *['a', 'b', 'c'])
5
>>> print lookup(d, *['a', 'c'])
None
bill_to = transactions['Transaction Details']['Bill To']

actually works. 实际上有效。 transactions['Transaction Details'] is an expression denoting a dict , so you can do lookup in it. transactions['Transaction Details']是表示dict的表达式,因此您可以在其中进行查找。 For practical programs, I would prefer an OO approach to nested dicts, though. 对于实际程序,我更喜欢OO方法来嵌套dicts。 collections.namedtuple is particularly useful for quickly setting up a bunch of classes that only contain data (and no behavior of their own). collections.namedtuple对于快速设置一组只包含数据(并且没有自己的行为)的类特别有用。

There's one caveat: in some settings, you might want to catch KeyError when doing lookups, and in this setting, that works too, it's hard to tell which dictionary lookup failed: 有一点需要注意:在某些设置中,您可能希望在执行查找时捕获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

Following is another way of accessing nested dictionaries 以下是访问嵌套字典的另一种方法

>>> 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
>>>

Here, variable 'name' refers to 'dbo['m']['d']['v']['version']', which seems much shorter and neat. 在这里,变量'name'指的是'dbo ['m'] ['d'] ['v'] ['version']',它看起来更短更整洁。

This method will not throw KeyError. 此方法不会抛出KeyError。 If a key is not found then you'll get 'None'. 如果找不到密钥,那么您将获得“无”。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM