[英]Converting a for loop to recursion in Python
I am new to recursion and am trying to convert a for loop to recursion. 我是递归的新手,正在尝试将for循环转换为递归。
allProducts = []
for a in range(10):
for b in range(10):
for c in range(10):
for d in range(10):
if (a*b*c*d)%6==0:
allProducts.append(a*b*c*d)
I am not able to convert this to a recursive program, which means I am not able to scale up. 我无法将其转换为递归程序,这意味着我无法扩大规模。 The idea is this - define a recursive program in Python that takes input A (number of for loops) and B (number which is a divisor of the product). 想法是这样的-在Python中定义一个递归程序,该程序接受输入A(for循环的数量)和B(该乘积的除数)。
Any help would be really helpful. 任何帮助都会非常有帮助。
You should have a look at the builtin package itertools
: 您应该看看内置的软件包itertools
:
for a,b,c,d in itertools.product(range(10),range(10),range(10),range(10)):
if (a*b*c*d)%6==0:
allProducts.append(a*b*c*d)
You can use itertools.product
and its repeat
argument: 您可以使用itertools.product
及其repeat
参数:
from operator import mul
import itertools
def myprod(n, div, repeat=4):
# i is a list of factors
for i in itertools.product(range(n), repeat=repeat):
# calculate product of all elements of list
prod = reduce(mul, i, 1)
if prod % div == 0:
yield prod
print list(myprod(10, 6))
Changing the repeat
argument of myprod
will change the number of loops and factors you are calculating. 更改myprod
的repeat
参数将更改您正在计算的循环数和因子。
Also, since multiplication is commutative ( a * b == b * a
) you should eliminate repetitive computations using itertools.combinations_with_replacement
: 另外,由于乘法是可交换的( a * b == b * a
),因此应使用itertools.combinations_with_replacement
消除重复计算:
from operator import mul
import itertools
def myprod_unique(n, div, repeat=4):
for i in itertools.combinations_with_replacement(range(n), r=repeat):
prod = reduce(mul, i, 1)
if prod % div == 0:
yield prod
print list(myprod_unique(10, 6))
If you remove duplicate results from myprod
using set
you will find that the two results are equal: 如果使用set
从myprod
删除重复的结果,则会发现两个结果相等:
print set(myprod_unique(10, 6)) == set(myprod(10, 6))
but you have cut down the number of operations drastically from n ** r
to (n+r-1)! / r! / (n-1)!
但您已将运算次数从n ** r
大大减少到(n+r-1)! / r! / (n-1)!
(n+r-1)! / r! / (n-1)!
. 。 For example 92,378 instead of 10,000,000,000 for n=10, r=10
. 例如,对于n=10, r=10
92,378代替10,000,000,000。
The other answers don't use recursion. 其他答案不使用递归。 For completeness, here is one that does. 为了完整起见,以下是一种方法。
Recursive functions usually have two parts. 递归函数通常包含两个部分。
Base case: Handled directly. 基本情况:直接处理。 Corresponds to the body of the innermost loop in your code. 对应于代码中最里面的循环的主体。
Recursive case: Involves calling the function again, corresponds to one for loop in your code. 递归的情况:涉及再次调用该函数,对应于代码中的一个for循环。
Sometimes extra parameters need to be introduced. 有时需要引入额外的参数。 In this example the variables a
, b
, etc. that have already been set need to be passed in. The natural way to do that is using a list. 在此示例中,需要传入已经设置的变量a
, b
等。完成此操作的自然方法是使用列表。
allProducts = []
def product(vals):
res = 1
for val in vals:
res *= val
return res
# n is the number of for loops remaining
# mod is the divisor
# vals is a list where the values of a, b, c, etc. will be placed
# start this function off using run(4, 6, [])
def run(n, mod, vals):
if n == 0:
# base case
if product(vals) % mod == 0:
allProducts.append(product(vals))
else:
# recursive case
for i in range(10):
# i takes the role of a, b, c, etc.
# add i to the vals
vals.append(i)
# recursively iterate over remaining n-1 variables
run(n - 1, mod, vals)
# remove i
vals.pop()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.