Search code examples
pythonfor-loopnested-for-loop

Python: Better way to write nested for loops and if statements


I am trying to find a more Pythonic way of doing the below.

for employee in get_employees:
    for jobs in employee['jobs']:
        for nemployee in employee_comps:
            if nemployee['employee_id'] == employee['id']:
                for njob in nemployee['hourly_compensations']:
                    if njob['job_id'] == jobs['id']:
                        njob['rate'] = jobs['rate']

It works but seems clunky. I'm new to Python, if there is another thread that will help with this please direct me there!


Solution

  • The main comment I would make about the code is that you are free to change the order of the outer three for loops because the operation that you are performing does not depend on the order that you loop over these (as you are not breaking out of any loops when finding a match), and that given that this is the case, there is no point in doing the jobs loop only to reach an if statement inside it that is independent of the value of jobs. It would be more efficient to put the jobs loop inside the other two, so that it can also be inside the if, i.e. the loop is only performed for those combinations of values of employee and nemployee where the if condition evaluates True.

    Beyond this but less importantly, where there are consecutive for statements (over independent iterables) after doing this rearrangement, you could replace them with a single loop over an itertools.product iterator to reduce the depth of nesting of for loops if you wish (reducing it from four to two explicit loops):

    from itertools import product
    
    for employee, nemployee in product(get_employees, employee_comps):
        if nemployee['employee_id'] == employee['id']:
            for jobs, njob in product(employee['jobs'],
                                      nemployee['hourly_compensations']):
                if njob['job_id'] == jobs['id']:
                    njob['rate'] = jobs['rate']