Как получить результат из словаря со списками в качестве значений

#python #python-3.x

Вопрос:

У меня есть файл JSON с n количеством словарей, как указано ниже в фрагменте. Я пытаюсь извлечь значение из ключа, но в моем коде это не удается, когда значение определяется как список, как в приведенном ниже примере для ключа affected_packages . Я попытался проверить, почему мой код не работает, так что, похоже, он не извлекает из него никаких данных, это не удается. Я просто вижу две скобки [] в качестве вывода вместо "thunderbird-0:78.9.1-1.el8_1","thunderbird-0:78.9.1-1.el8_2","thunderbird-0:78.9.1-1.el8_3","thunderbird-0:78.9.1-1.el7_9"

 {"bugzilla_description":"CVE-2021-23992 Mozilla: A crafted OpenPGP key with an invalid user ID could be used to confuse the user","cvss_score":null,"cvss_scoring_vector":null,"CWE":"CWE-347","affected_packages":["thunderbird-0:78.9.1-1.el8_1","thunderbird-0:78.9.1-1.el8_2","thunderbird-0:78.9.1-1.el8_3","thunderbird-0:78.9.1-1.el7_9"],"resource_url":"https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-23992.json","cvss3_scoring_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L","cvss3_score":"4.3"}
 

Я делаю то, что показано ниже в моем коде, так как мне нужно подготовить рабочий лист. Пример фрагмента:

 for i in range(offs):
    ws.cell(row=r 1 i,column=2).value = v['current'][i]
    if 'affected_packages' in list(tmp1.keys()):
          ws.cell(row=r 1 index1,column=11).value = tmp1['affected_packages']
          print("affected_packages done")
    if 'advisories' in list(tmp1.keys()):
          ws.cell(row=r 1 index2,column=13).value = tmp1['advisories']
          print("advisories done")
 

Есть ли способ, которым я могу правильно извлечь значение для тех, которые определены как список в словаре? Мне нужен способ, чтобы это не мешало моей существующей логике извлекать значение для обычного ключа: значение, так как при просмотре моего файла JSON.

Поэтому мне нужно что-то, что может соответствовать как моему значению в словаре в виде списка, так и не в виде списка, и я могу получить значение по ключам в моем файле json.

Ответ №1:

Как упоминалось в других ответах, вы можете проверить тип переменной с помощью

 if type(some_variable) == list: 
    # do what you need to do
 

Вы упоминаете, что ваш код прерывается, и я думаю, это потому, что при вставке в ячейку ожидается строка, а не список, который вы передаете в строке

           ws.cell(row=r 1 index1,column=11).value = tmp1['affected_packages']
 

Итак, как нам получить строку из списка строк? Это довольно просто с помощью метода соединения.

 my_list = ["thunderbird-0:78.9.1-1.el8_1","thunderbird-0:78.9.1-1.el8_2","thunderbird-0:78.9.1-1.el8_3","thunderbird-0:78.9.1-1.el7_9"]

as_one_string = ", ".join(my_list)
print(as_one_string)
# Prints out 'thunderbird-0:78.9.1-1.el8_1, thunderbird-0:78.9.1-1.el8_2, thunderbird-0:78.9.1-1.el8_3, thunderbird-0:78.9.1-1.el7_9'
 

Таким образом, объединив две идеи:

     if 'affected_packages' in list(tmp1.keys()):
          ws.cell(row=r 1 index1,column=11).value = tmp1['affected_packages'] if type(tmp1['affected_packages']) != list else ", ".join(tmp1['affected_packages'])
          print("affected_packages done")
 

Быстрая обратная связь, потому что я пока не могу комментировать: Пожалуйста, всегда указывайте сообщение об ошибке и/или вывод, который вы получаете при запуске кода, когда задаете вопрос

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

1. просто чтобы добавить сюда, он выбирает пустое значение — вывод идет как []

2. Как в ячейке в вашем рабочем листе пусто? или []

3. Кроме того, я допустил опечатку в последней строке своего кода, исправленную сейчас

4. он идет как [ ] вместо требуемого значения

5. Можете ли вы обновить свой вопрос кодом, в котором вы определяете tmp1? Также, когда вы говорите, что это выглядит как [], это на листе или когда вы печатаете tmp1[‘affected_packages’] в коде?

Ответ №2:

Если я правильно понимаю, вам просто нужно определить, является ли значение в dict списком. Вы можете сделать это, как показано ниже:

 for i in d.items(): # gets key, value as a tuple. 
   if isinstance(i[1],list):
       print('its a list, process it accordingly')
   else:
       print('Not a list')
 

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

1. Нет, мне нужно распечатать список так, как я делаю для значений, не входящих в список, как вы можете видеть в моем фрагменте кода

Ответ №3:

Что касается вашей второй проблемы, когда вы не знаете, список это или что-то еще, вы можете просто проверить тип, может быть, так:

 if type(tmp1['affected_packages']) == list:
    # process the list
else:
    # process other types
 

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