Python:编写嵌套的for循环和if语句的更好方法

问题描述

我正在尝试找到一种更Python化的方法来进行以下操作。

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']

它有效,但看起来笨拙。我是Python的新手,如果还有另一个线程可以帮助您解决此问题,请直接将我引导到那里!

解决方法

您拥有的代码非常干净和Pythonic,我建议您坚持使用。

如果您希望将其放在一行中,则此应该有效,但是我没有数据可以对其进行测试,所以我不确定。

[[njob.update({njob['rate']: jobs['rate']}) for njob in nemployee['hourly_compensations'] if njob['job_id'] == jobs['id']] for employee in get_employees for jobs in employee['jobs'] for nemployee in employee_comps if nemployee['employee_id'] == employee['id']]
,

我对代码的主要评论是,您可以自由更改外部三个for循环的顺序,因为您执行的操作并不取决于您对这些循环的顺序(因为您在找到匹配项时不会中断任何循环),并且鉴于这种情况,仅通过jobs循环来到达其中的if语句就没有意义了与jobs的值无关。将jobs循环放在其他两个循环内会更有效,这样它也可以位于if内,即,仅对employee的那些值组合执行循环和nemployee,其中if条件为True

除此以外,但不重要的是,在进行重新排列后有连续的for语句(在独立的可迭代对象上),您可以在itertools.product迭代器上用单个循环替换它们以减小深度。如果需要,可以嵌套for循环(将其从四个显式循环减少到两个显式循环):

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']