Python: лучший способ писать вложенные циклы и операторы if
Я пытаюсь найти более питонический способ сделать следующее.
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, если есть другой поток, который поможет с этим, пожалуйста, направьте меня туда!
2 ответа
Основной комментарий, который я хотел бы сделать по поводу кода, заключается в том, что вы можете изменить порядок внешних трех 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']
Ваш код очень чистый и питонический, я бы посоветовал ему остаться.
Если вы хотите, чтобы это было в одной строке, это должно сработать, но у меня нет данных для проверки, поэтому я не уверен.
[[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']]