Search code examples
pythonamazon-web-servicesamazon-ec2aws-lambdaboto3

How to avoid nested loops in python parsing aws


I'm relatively new to python and I don't know all the mysteries of this language yet so I was wondering if there are any ways I can optimize this code.

I'm trying to list the name of my EC2 instances in an AWS lambda using boto3 and python.

Here's the code :

import json
import boto3
import botocore
import logging

# Create a logging message
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(name)s:%(message)s')

# Create EC2 resource
ec2 = boto3.client('ec2')

ec2_list = ec2.describe_instances()

def lambda_handler(event, context):

    try:
        for reservation in ec2_list['Reservations']:
            for instance in reservation['Instances']:
                for tag in instance['Tags']:
                    print(tag['Value'])
        return {
            'statusCode': 200,
            'body': json.dumps('Hello from Lambda!')
        }
    except botocore.exceptions.ClientError as e:
        logger.debug(e)
        raise e

I also tried that as seen in another post, but it didnt work, because reservation var is referenced before assignment - seems logic:

for reservation, instance, tag in itertools.product(ec2_list['Reservations'], reservation['Instances'], instance['Tags']):
            print(tag['Value'])

And here is the thing I need to parse (I reduced it a lottttt for the post) :

[
    {
        'Groups': [],
        'Instances': [
            {
                'Tags': [
                    {
                        'Key': 'Name',
                        'Value': 'Second Instance'
                    }
                ],
            }
        ],
    },
    {
        'Groups': [],
        'Instances': [
            {
                'Tags': [
                    {
                        'Key': 'Name',
                        'Value': 'First Instance'
                    }
                ],
            }
        ],
    }
]

So, right now it's working and I got the 'Value' that I want, but I would like to know if there are ways to simplify/optimize it ? I'm not good at list comprehension yet, so maybe this way ?

Thank you !


Solution

  • You can do it in one line using list comprehensions, but at the end it is similar to have nested loops:

    tags = [tag['Value'] for res in ec2_list['Reservations'] for instances in res['Instances'] for tag in instances['Tags']]
    

    What you get is a list with all the 'Values' like this one:

    print(tags)
    # ['Second Instance', 'First Instance']