如何使用Python在深度嵌套的结构中收集特定值

时间:2018-11-19 17:53:41

标签: python for-loop nested-loops

我正在尝试获取在Python脚本中使用boto3 api从describe_instances调用中获取的实例ID的列表。对于那些不了解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新手,所以我真的认为必须有一些更好的方法来做到这一点,而不是多个forif。有一个更好的方法吗?请指出结构/方法等,这可能对我的情况有用

1 个答案:

答案 0 :(得分:1)

您的解决方案实际上并没有那么低效,除非您不必为了保存实例ID而创建所有顶级列表。您可以做的是嵌套循环并仅保留您需要的内容:

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

是的,有很多方法可以用较短的代码来做到这一点,但是 explicit优于隐式,并坚持阅读得最好。 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)]