Если ваша функция слишком повторяющаяся, вы можете пошагово реорганизовать вещи.
Общность, которую вы хотите выделить, - это вызов myfunction2(a, b)
на каком-то итераторе.Но второй итератор имеет не только product
аргументы, но и элементы каждой пары.Итак:
def f(first_loop_on_a=True):
if first_loop_on_a:
prod = product(range(10), range(5))
else:
prod = (b, a for (a, b) in product(range(5), range(10)))
for a, b in prod:
myfunction2(a, b)
Если вы делаете это несколько раз, вы можете выделить этот переворот в функцию:
def flippair(p):
a, b = p
return b, a
def f(first_loop_on_a=True):
if first_loop_on_a:
prod = product(range(10), range(5))
else:
prod = map(flippair, product(range(5), range(10)))
for a, b in prod:
myfunction2(a, b)
(или, конечно,flippair
может просто вернуть p[::-1]
- или, так как вам не нужны кортежи, а просто какой-либо тип итерации, просто используйте reversed
. Но этот способ кажется более явным и все же достаточно кратким.)
Но я думаю, что лучшее решение - использовать аргументы ключевых слов для myfunction
:
def kwify(order, pairs):
return (dict(zip(order, pair)) for pair in pairs)
def f(first_loop_on_a=True):
if first_loop_on_a:
prod = kwify('ab', product(range(10), range(5)))
else:
prod = kwify('ba', product(range(5), range(10)))
for kwpair in prod:
myfunction2(**kwpair)
. Это действительно делает очевидным, что вы передаете a
значения как a
иb
значения как b
, вместо того, чтобы переворачивать их, чтобы они оказались в b
и a
, а затем переворачивать их, чтобы передать их в обратном порядке.
Пока мызачем повторять диапазоны?
def kwify(order, pairs):
return (dict(zip(order, pair)) for pair in pairs)
def f(first_loop_on_a=True):
arange, brange = range(10), range(5)
if first_loop_on_a:
prod = kwify('ab', product(arange, brange))
else:
prod = kwify('ba', product(brange, arange))
for kwpair in prod:
myfunction2(**kwpair)
… и в этот момент вы также можете дать их имен:
def kwify(order, pairs):
return (dict(zip(order, pair)) for pair in pairs)
def f(first_loop_on_a=True):
ranges = {'a': range(10), 'b': range(5)}
order = 'ab' if first_loop_on_a else 'ba'
prod = kwify(order, product(*itemgetter(*order)(ranges)))
for kwpair in prod:
myfunction2(**kwpair)
... или, может быть, даже отстранить от звонков range
:
def kwify(order, pairs):
return (dict(zip(order, pair)) for pair in pairs)
def f(first_loop_on_a=True):
ranges = {'a': 10, 'b': 5}
order = 'ab' if first_loop_on_a else 'ba'
prod = kwify(order, product(*map(range, itemgetter(*order)(ranges))))
for kwpair in prod:
myfunction2(**kwpair)
Это, вероятно, ужасное излишество - просто выбрать «a-then-b» против «b-then-a», bНо если вы хотите, чтобы это распространялось на выбор различных комбинаций трех переменных или произвольных порядков из динамического списка и т. д., это, вероятно, стоило бы сделать.