У меня есть объект json, который я получаю после вызова, похожий на этот:

{
    'Tags': [
        {
            'Key': 'Dept',
            'PropagateAtLaunch': True,
            'ResourceId': 'my-auto-scaling-group',
            'ResourceType': 'auto-scaling-group',
            'Value': 'Research',
        },
        {
            'Key': 'Role',
            'PropagateAtLaunch': True,
            'ResourceId': 'my-auto-scaling-group',
            'ResourceType': 'auto-scaling-group',
            'Value': 'WebServer',
        },
        {
            'Key': 'ecs_scaling',
            'PropagateAtLaunch': True,
            'ResourceId': 'my-auto-scaling-group',
            'ResourceType': 'auto-scaling-group',
            'Value': 'true',
        },
    ],
    'ResponseMetadata': {
        '...': '...',
    },
}

Есть ли более Pythonic способ просто определить, существует ли Ключ ecs_scaling, кроме стандартного:

data = json.loads(theThing)
for key in data.items():
   ... 

Ключ может быть первым элементом, это может быть 40-й элемент - в идеале я хотел бы иметь возможность сделать что-то вроде if 'ecs_scaling' in theKeys: ...?

3
MrDuk 30 Авг 2017 в 18:17

4 ответа

Лучший ответ

Вы можете использовать встроенный any.

Верните True, если какой-либо элемент итерации истинен. Если итерируемый объект пуст, верните False.

if any(tag['key'] == 'ecs_scaling' for tag in data['Tags']):
    ...
4
Zach Gates 30 Авг 2017 в 15:21

Я думал, может ли быть другой способ сделать это. Хотя это немного забавно;) но это сработает и уменьшит вызов любых build-in методов для этого. Однако я сомневаюсь, что я выполняю критерии, делающие это питонским способом.

Однако я определенно рассматриваю тот факт, что Key и его значение ecs_scaling будут существовать в нужном разделе данных, т.е. Tags. Наряду с этим шаблоны должны быть исправлены, в противном случае решение не сработает, т. Е. "Key": "ecs_scaling", как мне кажется, будет, если бы это был дикт, до того, как он пришел сюда в виде строки.

Просто используйте str.find, но вам может потребоваться вызвать его дважды, чтобы обеспечить желаемый результат. { { Х1 }}

Но да any является одним из лучших решений, если мы игнорируем недостатки не проверять, существует ли, до проверки всего набора данных.

0
MaNKuR 30 Авг 2017 в 16:37

Сложность уже линейна, поэтому единственное, на что можно надеяться - это поиск по хешу. Однако построение хеш-набора или хеш-таблицы потребует линейной сложности.

Поэтому, если функции, которые вы вызываете из модуля json, уже не создают такой хэш-набор, итерация - лучшее, что вы можете сделать для линейной сложности, т.е. O(n).

В связи с этим, я думаю, что наиболее Pythonic подход использует встроенный any, уже упомянутый другим.

Ради полноты, хотя это было бы менее производительно, вы могли бы также использовать понимание списка, которое часто считается «высокопифоническим»:

'ecs_scaling' in [item['Key'] for item in data.items()]

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

3
Right leg 30 Авг 2017 в 15:33
any(el['Key'] == 'ecs_scaling' for el in data['Tags'])
2
Ignacio Vazquez-Abrams 30 Авг 2017 в 15:20
45964144