Получить словарь в списке, где есть определенные пары ключ-значение

#python #json #list #dictionary

#python #json #Список #словарь

Вопрос:

Предполагая, что у меня есть этот словарь внутри списка:

  [
    {
        "Name": "Person",
        "Confidence": 97.56156921386719,
        "Instances": [
            {
                "BoundingBox": {
                    "Width": 0.6137702465057373,
                    "Height": 0.9175498485565186,
                    "Left": 0.22297996282577515,
                    "Top": 0.0739903450012207
                },
                "Confidence": 94.51961517333984
            },
            {
                "BoundingBox": {
                    "Width": 0.46570318937301636,
                    "Height": 0.6405649781227112,
                    "Left": 0.11447866261005402,
                    "Top": 0.34079012274742126
                },
                "Confidence": 82.2153549194336
            }
        ],
        "Parents": []
    },
    {
        "Name": "Human",
        "Confidence": 97.56156921386719,
        "Instances": [],
        "Parents": []
    },
    {
        "Name": "Clothing",
        "Confidence": 91.08417510986328,
        "Instances": [],
        "Parents": []
    }
    }]
  

Как я могу получить словарь только с ключевым значением «Имя»: «Одежда»? возможно ли извлечь его из словаря? Ключ «Одежда» может появиться в любой части списка.

     {
        "Name": "Clothing",
        "Confidence": 91.08417510986328,
        "Instances": [],
        "Parents": []
    }
  
  

Ответ №1:

Вы можете использовать следующий код, чтобы получить каждый элемент Name , который имеет Clothing :

 names = [
    {
        "Name": "Person",
        "Confidence": 97.56156921386719,
        "Instances": [
            {
                "BoundingBox": {
                    "Width": 0.6137702465057373,
                    "Height": 0.9175498485565186,
                    "Left": 0.22297996282577515,
                    "Top": 0.0739903450012207
                },
                "Confidence": 94.51961517333984
            },
            {
                "BoundingBox": {
                    "Width": 0.46570318937301636,
                    "Height": 0.6405649781227112,
                    "Left": 0.11447866261005402,
                    "Top": 0.34079012274742126
                },
                "Confidence": 82.2153549194336
            }
        ],
        "Parents": []
    },
    {
        "Name": "Human",
        "Confidence": 97.56156921386719,
        "Instances": [],
        "Parents": []
    },
    {
        "Name": "Clothing",
        "Confidence": 91.08417510986328,
        "Instances": [],
        "Parents": []
    }
]

for name in names:
    if name['Name'] == 'Clothing':
        print(name)

  

Если вы хотите, чтобы он был коротким, вы можете использовать следующий код:

 x = [y for y in names if name['Name'] == 'Clothing']
  

Ответ №2:

Здесь .get(Key, defaultValue) можно использовать.

.get("Name", "") —> Возвращает пустую строку, если ключ Name не существует в словаре. doc
.get("Name") —> Возвращает None , если Name не существует.

Таковы .get("Name") == "Clothing" критерии выбора словаря.

И используйте filter(), чтобы выбрать только те, которые удовлетворяют критериям.

Собрать все это вместе

 filter(lambda x: x.get("Name") == "Clothing", mylist)
  

filter возвращает итератор, поэтому вы можете передать его в list для создания полного списка.
Если вы просто хотите перебрать его, не нужно вызывать list .

Итак,

 list(filter(lambda x: x.get("Name") == "Clothing", mylist))
  

Ответ №3:

Вы можете использовать этот простой list comprehension :

 [print(dictionary) for dictionary in lst if 'Name' in dictionary.keys() and dictionary['Name'] == 'Clothing']
  

Вывод:

 {'Name': 'Clothing', 'Confidence': 91.08417510986328, 'Instances': [], 'Parents': []}
  

Вот полный код:

 lst =  [
    {
        "Name": "Person",
        "Confidence": 97.56156921386719,
        "Instances": [
            {
                "BoundingBox": {
                    "Width": 0.6137702465057373,
                    "Height": 0.9175498485565186,
                    "Left": 0.22297996282577515,
                    "Top": 0.0739903450012207
                },
                "Confidence": 94.51961517333984
            },
            {
                "BoundingBox": {
                    "Width": 0.46570318937301636,
                    "Height": 0.6405649781227112,
                    "Left": 0.11447866261005402,
                    "Top": 0.34079012274742126
                },
                "Confidence": 82.2153549194336
            }
        ],
        "Parents": []
    },
    {
        "Name": "Human",
        "Confidence": 97.56156921386719,
        "Instances": [],
        "Parents": []
    },
    {
        "Name": "Clothing",
        "Confidence": 91.08417510986328,
        "Instances": [],
        "Parents": []
    }
]

[print(dictionary) for dictionary in lst if 'Name' in dictionary.keys() and dictionary['Name'] == 'Clothing']
  

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

1. любой pythonic стиль для этого? или так лучше?

2. Вы можете использовать понимание списка, как я упоминал выше. Понимание списков более питоническое

3. Я бы не стал печатать в понимании списка, но понимание списка — это типичный способ фильтрации списка.

4. Да … я согласен. Но является ли печать элементов в понимании списка не очень хорошим способом кодирования?

5. Я проголосовал; одно небольшое изменение, которое я бы внес, — заменить условие в понимании списка на dictionary.get("Name") == "Clothing" .

Ответ №4:

Предполагая, что ваш список вызывается my_list , тогда это должно дать вам то, что вы хотите:

my_list_new = [x for x in my_list if ("Name", "Clothing") in x.items()]

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

1. через несколько минут это будет помечено как ответ, я выбираю этот, поскольку он короче предыдущего ответа

2. Проголосовал против. if ("Name", "Clothing") in x.items() излишне неэффективно и нечитаемо. Это игнорирует весь смысл использования dict .

3. @blhsing согласен. Для тех, кто задается вопросом, почему это неэффективно. Это понимание списка должно быть вызвано x.items() для каждого словаря x в my_list. И он выполняет линейный поиск кортежа («Имя», «Одежда») для каждого из этих результатов. Для всех словарей, в которых нет этого кортежа, он будет считывать каждую отдельную пару ключ-значение, чтобы выбрать не включать x.

4. я вижу. Спасибо за отзыв