Получить значение из списка вложенных dict в Python на основе ключа

#python

#python

Вопрос:

У меня есть список dict, нужно получить int_value из подраздела значений, основанного на значении ключа.

 my_list = [{'key': 'previous_id',
  'value': {'int_value': '-4343583665607944462'}},
 {'key': 'event_origin', 'value': {'string_value': 'auto'}},
 {'key': 'screen_id', 'value': {'int_value': '-5880567181845583757'}},
 {'key': 'previous_class', 'value': {'string_value': 'MainActivity'}},
 {'key': 'screen', 'value': {'string_value': 'Gateway'}},
 {'key': 'screen_class', 'value': {'string_value': 'Gateway'}}]
  

Например, мне нужно получить -4343583665607944462 в качестве строкового вывода для previous_id.

Это то, что я получил до сих пор, что кажется мне слишком сложным, хочу знать, есть ли более простой способ добиться этого.

 for d in my_list:
    if list(d.values())[0] == 'previous_id':
        print(list(d.values())[1].values())
  

Получаем -4343583665607944462 в виде строки, выводимой для previous_id.

Пожалуйста, также предложите, имеет ли смысл определять функцию.

Комментарии:

1. for dict_ in my_list:..if dict_['key'] == 'previous_id':....yield dict_['value']['int_value'] ?

Ответ №1:

Возможно, стоит предварительно обработать ваш первоначальный список dict, что-то вроде:

 key_to_int = {}
for d in my_list:
    if 'int_value' in d['value']:
        key_to_int[d['key']] = d['value']['int_value']
    else:
        key_to_int[d['key']] = None
  

Затем вы можете просто сделать:

 print(key_to_int['previous_id'])
print(key_to_int['event_origin'])
print(key_to_int['screen_id'])
  

Который выводит:

 -4343583665607944462
None
-5880567181845583757
  

Вышесказанное предполагает, что все ваши dict соответствуют одному и тому же формату. В случае, когда некоторые dict могут быть вложены глубже, чем другие, необходимо внести некоторые изменения.

Комментарии:

1. Спасибо за ответ. В итоге я создал метод для предварительной обработки списка с вводом типа списка и значения, чтобы я мог использовать то же самое для получения int_value и string_value.

Ответ №2:

Я бы предложил проверить, является ли первое значение "previous_id" с помощью "key" ключа, а не .values()[0] , и то же самое для получения значения. Если вы знаете ключи заранее, это рекомендуемый способ доступа к данным из словаря.

Если вы хотите упростить свой код, вы могли бы использовать next функцию, которая выполняет цикл по итерируемому и возвращает первое найденное значение (которое соответствует заданному условию, если оно существует).

Например:

 value = next(d["value"] for d in my_list if d["key"] == "previous_id")
  

Это вернет

 {'int_value': '-4343583665607944462'}
  

Если вы хотите просто "-4343583665607944462" , то вы могли бы сделать:

 value = next(list(d["value"].values())[0] for d in my_list if d["key"] == "previous_id")
  

Обратите внимание, что здесь мы используем .values()[0] , потому что ключи не всегда совпадают.

Также next вызывает StopIteration исключение, если оно достигает конца итерации, не найдя соответствия, поэтому подумайте о том, чтобы обернуть его в блок try / except .

Ответ №3:

Я не знаю, есть ли у вас доступ к предварительному изменению фактического списка, но, вероятно, было бы разумнее сохранить тип значения внутри одного dict, например:

 my_list = [{
    'key': 'previous_id',
    'value': '-4343583665607944462',
    'type': 'int_value' },...]
  

Таким образом, вы могли бы просто вызвать:

 for dict in my_list:
    if dict['key']=='previous_id':
        return dict['value']
  

или однострочный:

 value = [x['values'] for x in my_list if x['key']=='previous_id']
  

и если вы заинтересованы в типе значения

 value = {x['type']:x['values'] for x in my_list if x['key']=='previous_id'}
  

Ответ №4:

Если вы хотите использовать тот же словарь и придерживаться своего метода, вы можете использовать:

 for d in my_list:
    if d["key"] == 'previous_id':
        print(list(d["value"].values())[0])
  

Но я бы рекомендовал вам использовать словарь, подобный этому:

 my_dict = {"previous_id": '-4343583665607944462', 'event_origin':'auto',  
    'screen_id':-5880567181845583757,  'previous_class': 'MainActivity',
    'screen': 'Gateway',  'screen_class': 'Gateway'}
  

Затем вы можете использовать print просто так:

 print(my_dict["previous_id"])