Итерация по вложенному словарю yaml из python - PullRequest
0 голосов
/ 14 марта 2019

Я безопасно загрузил объект python, проанализировав документ yaml, аналогичный приведенному ниже формату,

envdata = yaml.safe_load (данные)

id: XXX
name: XXX
tecVersion: 1

wrapper: #category
    wrapper-box-1: #instance
        host: XXX
        port: 4567
        tags:
          - ABC
          - VTR


powerWrapper: #category
     pw-box-45: #instance
         host: YYY
         port: 7890
         tags:
           - ABC

Каждая категория является объектом массива верхнего уровня, а экземпляр является объектом массива внутри категории.

Требование, учитывая тег ex: ABC, я хочу получить все соответствующие экземпляры в каждой категории в виде списка. Как я могу перебрать каждый элемент, сравнить теги и оптимально добавить все совпадающие экземпляры в массив экземпляров?

1 Ответ

1 голос
/ 15 марта 2019

(1.) Каждая категория является объектом массива верхнего уровня, а экземпляр является объектом массива внутри категории.

(2.) Как я могу ... сравнить теги и добавить все совпадающие экземпляры в массив экземпляров ...?

Определение в (1.) не совсем потрясающее, но этого достаточно для работы. Я не согласен с вашим использованием слова «массив» или list, когда, по-видимому, «карта» или dict - это то, что содержит категория. Мне кажется, было бы немного приятнее, если бы каждый экземпляр гарантированно содержал ключ с именем 'instance' или 'id' или что-то подобное, чтобы отличить их от записей одного уровня, таких как 'tecVersion'. В качестве альтернативы, все экземпляры могут быть сдвинуты на один уровень вниз под клавишей с креативным именем, например, давайте посмотрим, может быть, мы бы назвали это 'instances'?

Вы дали понять, что 'wrapper' - это "категория". Я не знаю, как можно назвать 'wrapper-box-1'. Жаль, что вы не включили 'wrapper-box-2' в данные своего примера.

Вот что возвращает yaml:

>>> pprint.pprint(envdata)
{'id': 'XXX',
 'name': 'XXX',
 'powerWrapper': {'pw-box-45': {'host': 'YYY', 'port': 7890, 'tags': ['ABC']}},
 'tecVersion': 1,
 'wrapper': {'wrapper-box-1': {'host': 'XXX',
                               'port': 4567,
                               'tags': ['ABC', 'VTR']}}}

Хорошо, давайте повторим:

def get_tags(putative_category):
    """Generator, returns tags if the input appears to be a category."""
    try:
        for undefined_box_concept, attributes in putative_category.items():
            tags = attributes['tags']
            yield tags
    except (AttributeError, KeyError):
        pass

for category_name, category in envdata.items():
    for tags in get_tags(category):
        print(tags, category_name, category)

Выход:

['ABC', 'VTR'] wrapper {'wrapper-box-1': {'host': 'XXX', 'port': 4567, 'tags': ['ABC', 'VTR']}}
['ABC'] powerWrapper {'pw-box-45': {'host': 'YYY', 'port': 7890, 'tags': ['ABC']}}

Ваше постановка проблемы немного расплывчато. Когда у вас есть метки в руках, мне не ясно, что вы хотите с ними делать. Для (2.) должно быть достаточно понимания списка с вложенными циклами for, используя предоставленный мной генератор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...