我有一个字典,其中包含字典,也可能包含字典,例如
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']
是否有更简单的方法可以深入挖掘嵌套字典而无需解压缩到临时变量中?
答案 0 :(得分:20)
您可以使用以下内容:
>>> 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
答案 1 :(得分:14)
bill_to = transactions['Transaction Details']['Bill To']
实际上有效。 transactions['Transaction Details']
是表示dict
的表达式,因此您可以在其中进行查找。对于实际程序,我更喜欢OO方法来嵌套dicts。 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
答案 2 :(得分: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
>>>
这里,变量名称'指的是' m' [' d'] [' v'] ['版本']&#39 ;,这似乎更短,更整洁。
此方法不会抛出KeyError。如果找不到密钥,那么您将获得“无”#。
参考:http://code.activestate.com/recipes/475156-using-reduce-to-access-deeply-nested-dictionaries/