如何pythonically多次使用.get()?

Har*_*ton 2 python dictionary

使用多次访问不同级别的dict 的最pythonic /有效方法是什么?<dict>.get('<key>')

(这些例子故意短,但想象更多的键和更长的原始字典)

一个例子:

而不是这个:

    complete_data = {'name': 'bob',
                     'age':'22',
                     'items': [{'subitem':1,'another subitem':2}, 123, 456]}

    required_data['name'] = complete_data['name']

    required_data['another subitem'] = complete_data['items'][0]['another subitem']
Run Code Online (Sandbox Code Playgroud)

我们可以使用这样的东西:

    complete_data = {'name': 'bob', 'age':'22', 'other stuff': 'some stuff'}

    desired_keys = ['name','age']

    for i in range(len(desired_keys)):
        required_data[desired_keys[i]] = complete_data[desired_keys[i]]
Run Code Online (Sandbox Code Playgroud)

(但要complete_data['items'][0]['another subitem']在字典中找到更深层次的东西(?))

一些上下文:API发送的信息超出了我的需要.信息打包为dict,其中包含更多子序列和列表.我试图尽可能有效地提取信息,因为我必须重复这一百万次以上.我也希望尽可能高效地编写代码,因为我必须为多个API修改它.

Ara*_*Fey 6

您可以将密钥存储在列表中,然后编写一个函数来为您执行项目查找:

from functools import reduce
import operator

def lookup(container, keys):
    return reduce(operator.getitem, keys, container)
Run Code Online (Sandbox Code Playgroud)

有了这个,complete_data['items'][0]['another subitem']变成了

lookup(complete_data, ['items', 0, 'another subitem'])
Run Code Online (Sandbox Code Playgroud)

或者,这是一个故障安全实现:

def lookup(container, keys, default=None):
    try:
        return reduce(operator.getitem, keys, container)
    except (IndexError, KeyError):
        return default
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用它轻松收集所需的所有数据:

desired_keys=  {'name': ['name'],
                'another subitem': ['items', 0, 'another subitem']}

required_data= {}
for key, keys in desired_keys.items():
    required_data[key]= lookup(complete_data, keys)

print(required_data)
# output: {'name': 'bob', 'another subitem': 2}
Run Code Online (Sandbox Code Playgroud)

  • @Harrydewinton它会抛出一个`KeyError`或`IndexError`.如果这是一个问题,只需将函数体包装在`try:... except(KeyError,IndexError)中:return None`. (2认同)
  • @Harrydewinton几乎可以肯定,因为在python中实现的更少.但我不认为差异会很明显. (2认同)