访问嵌套在字典中的值
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
【讨论】:
以上是关于访问嵌套在字典中的值的主要内容,如果未能解决你的问题,请参考以下文章