如何根据另一个键的值从嵌套(并非总是存在)字典列表中提取给定键的值 [Python]

How to extract the value of a given key based on the value of another key, from a list of nested (not-always-existing) dictionaries [Python]

我有一个名为 api_data 的字典的 列表 ,其中每个字典都具有以下结构:

{

'location': 
    {
    'indoor': 0, 
    'exact_location': 0, 
    'latitude': '45.502', 
    'altitude': '133.9', 
    'id': 12780, 
    'country': 'IT', 
    'longitude': '9.146'
    },

'sampling_rate': None, 
'id': 91976363, 
'sensordatavalues': 
    [   
        {
        'value_type': 'P1', 
        'value': '8.85', 
        'id': 197572463
        }, 


        {
        'value_type': 'P2', 
        'value': '3.95', 
        'id': 197572466
        }

        {
        'value_type': 'temperature', 
        'value': '20.80', 
        'id': 197572625
        }, 

        {
        'value_type': 'humidity', 
        'value': '97.70', 
        'id': 197572626
        }
    ], 

'sensor': 
    {
    'id': 24645, 
    'sensor_type': 
        {
        'name': 'DHT22', 
        'id': 9, 
        'manufacturer': 
        'various'
        }, 

    'pin': '7'
    }, 

'timestamp': '2020-04-18 18:37:50'

},

每个字典的结构都不完整,这意味着有时会缺少字典、列表元素或键。

我想在同一个字典的键值等于某个值时提取某个键的值
例如,对于字典 sensordatavalues,当 'value_type' 等于 'P1'.

时,我想要键 'value' 的值

我已经开发了这段使用 for 和 if 循环的代码,但我敢打赌它的效率非常低。 我怎样才能更快更有效地做到这一点?

请注意sensordatavalues总是存在

for sensor in api_data:

    sensordatavalues = sensor['sensordatavalues']
    # L_sdv = len(sensordatavalues)

    for physical_quantity_recorded in sensordatavalues:

        if physical_quantity_recorded['value_type'] == 'P1':

            PM10_value = physical_quantity_recorded['value']               

你只需要一个 for 循环:

for x in api_data["sensordatavalues"]:
    if x["value_type"] == "P1":
        print(x["value"])

输出:

8.85

使用dictionary.get()方法如果键不存在它将return默认值

for physical_quantity_recorded in api_data['sensordatavalues']:
    if physical_quantity_recorded.get('value_type', 'default_value') == 'P1':
        PM10_value = physical_quantity_recorded.get('value', 'default_value')
  1. 如果您确信值 'P1' 对于您正在搜索的键是唯一的,您可以将 'in' 运算符与 dict.values()
  2. 一起使用
  3. 省略这个赋值应该没问题:sensordatavalues = sensor['sensordatavalues']
for sensor in api_data:

    for physical_quantity_recorded in sensor['sensordatavalues']:

        if 'P1' in physical_quantity_recorded.values():

            PM10_value = physical_quantity_recorded['value'] 

这是一个替代方案:jmespath - 允许您搜索和过滤嵌套的 dict/json :

jmespath 摘要 ... 要访问键,请使用 . 表示法,如果您的值在列表中,您可以通过 [] 表示法

访问它

注意:dict 被包装在一个 data 变量中

import jmespath
#sensordatavalues is a key, so we can access it directly
#the values of sensordatavalues are wrapped in a list
#to access it we pass the bracket(```[]```)
#we are interested in the dict where value_type is P1
#in jmespath, we identify that using the ? mark to precede the filter object
#pass the filter
#and finally access the key we are interested in ... value

expression = jmespath.compile('sensordatavalues[?value_type==`P1`].value')
expression.search(data)
['8.85']