问题描述
我正在尝试找到一种更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']