Упрощение итераций Python
Каждый раз, когда я пытаюсь решить какую-то математическую задачу, такую как поиск определенного продукта с определенным количеством факторов, я делаю это в Python
for x in xrange(1,10):
for y in xrange(1,10):
for z in xrange(1,10):
product = x * y * z
if product == 36:
print "factors : {0},{1},{2}".format(x,y,z)
Это очень просто и быстро выполняет работу в этом примере, но мне было интересно, знаете ли вы, ребята, более простой или простой способ написать это. Любые идеи о том, как сделать это, не используя это много для итераций или повторяя почти один и тот же код снова и снова. Это очевидно для трех факторов, но чем больше я добавляю факторов, тем длиннее и повторяющимся становится код. Любые идеи о том, как упростить код для этого простого типа проблемы? Спасибо
2 ответа
Картезианский продукт Itertool имитирует эффект множественных вложенных циклов.
import itertools
for x, y, z in itertools.product(range(1,10), range(1,10), range(1,10)):
product = x * y * z
if product == 36:
print "factors : {0},{1},{2}".format(x,y,z)
Результат:
factors : 1,4,9
factors : 1,6,6
factors : 1,9,4
(...etc)
Если диапазон всегда одинаков для каждого из x,y и z, вы можете указать его только один раз:
for x, y, z in itertools.product(range(1,10), repeat=3):
Если вам надоело набирать миллион звездочек для product =
линия, вы можете использовать reduce
умножить произвольное количество аргументов:
for factors in itertools.product(range(1,3), repeat=10):
product = reduce(lambda x, y: x*y, factors)
Как только ваша строка формата станет громоздкой, вы можете зависеть от join
объединить факторы:
if product == 512:
#use `map` to turn the factors into strings, first
print "factors: " + ",".join(map(str, factors))
Избегайте дубликатов, имея y
начать с x
, подсчитывать z
вместо запуска другого цикла.
for x in xrange(1,10):
for y in xrange(x,10):
z, r = divmod(36, x*y)
if r == 0:
print "factors : {0},{1},{2}".format(x,y,z)
Для большего количества факторов я бы использовал рекурсивную функцию.