Как собрать конкретные значения в глубоко вложенной структуре с Python - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь получить список идентификаторов экземпляров, которые я получаю из вызова describe_instances, используя apto boto3 в моем скрипте python. Для тех из вас, кто не знает о aws, я могу опубликовать подробный код после удаления подробностей, если вам это нужно. Я пытаюсь получить доступ к элементу из структуры, подобной этой

   u'Reservations':[  
      {  
         u'Instances':[  
            {
              u'InstanceId':'i-0000ffffdd'
            },
            {  },   ### each of these dict contain a id like above
            {  },
            {  },
            {  }
         ]
      },
      {  
         u'Instances':[  
            {  },
            {  },
            {  },
            {  },
            {  }
         ]
      },
      {  
         u'Instances':[  
            {  }
         ]         
      }
]

Я сейчас получаю к нему доступ как

instanceLdict = []
instanceList = []
instances = []
for r in reservations:
  instanceList.append(r['Instances'])
for ilist in instanceList:
   for i in ilist:
       instanceLdict.append(i)
for i in instanceLdict:
    instances.append(i['InstanceId']) ####i need them in a list
print instances

fyi: моя переменная reservations содержит весь список u'Reservations':

Я чувствую, что это неэффективно, и, поскольку я новичок в Python, я действительно думаю, что должен быть какой-то лучший способ сделать это, а не несколько for и if. Есть лучший способ сделать это? Пожалуйста, укажите структуру / метод и т. Д., Которые могут быть полезны в моем сценарии

1 Ответ

0 голосов
/ 20 ноября 2018

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

instances = list()
for r in reservations:
  for ilist in r['Instances']:
    for i in ilist:
      instances.append(i['InstanceId'])  # That's what you looping for

Да, есть способы сделать это с более коротким кодом, но явный лучше, чем неявный и придерживатьсяк тому, что вы можете прочитать лучше всего.Python неплохо справляется с итерациями и запоминает удобство сопровождения в первую очередь, производительность во втором .Кроме того, эта часть вряд ли является узким местом того, что вы делаете после всех этих вызовов API, поисков в БД и т. Д.

Но если вы действительно настаиваете на том, чтобы делать модные однострочные, посмотрите на itertools помощников, chain.from_iterable() - это то, что вам нужно:

from itertools import chain
instances = [i['InstanceId'] for i in chain.from_iterable(r['Instances'] for r in reservations)]
...