问题与Python递归
问题描述:
我已经写在Python 2.7以下代码找到N A组(AxAxA ... XA)的时间笛卡尔积 -问题与Python递归
prod=[]
def cartesian_product(set1,set2,n):
if n>=1:
for x in set1:
for y in set2:
prod.append('%s,%s'%(x,y))
#prod='[%s]' % ', '.join(map(str, prod))
#print prod
cartesian_product(set1,prod,n-1)
else:
print prod
n=raw_input("Number of times to roll: ")
events=["1","2","3","4","5","6"]
cartesian_product(events,events,1)
这正常工作当n = 1。但是从cartesian_product改变参数值(事件,事件1)到cartesian_product(事件,事件,2)不起作用。似乎有一个无限循环正在运行。我无法确定我在哪里犯了一个错误。
答
def cartesian_product(*X):
if len(X) == 1: #special case, only X1
return [ (x0,) for x0 in X[0] ]
else:
return [ (x0,)+t1 for x0 in X[0] for t1 in cartesian_product(*X[1:]) ]
n=int(raw_input("Number of times to roll: "))
events=[1,2,3,4,5,6]
prod=[]
for arg in range(n+1):
prod.append(events)
print cartesian_product(*prod)
输出:
Number of times to roll: 1
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6)]
你也可以通过串在你的事件列表中,但它会在元组打印字符串也。
答
当您将递归调用的全局变量prod
的引用传递给您时,您正在修改set2
也引用的列表。这意味着set2
在迭代时正在增长,这意味着迭代器永远不会结束。
这里不需要全局变量。 返回改为计算的产品。
def cartesian_product(set1, n):
# Return a set of n-tuples
rv = set()
if n == 0:
# Degenerate case: A^0 == the set containing the empty tuple
rv.add(())
else:
rv = set()
for x in set1:
for y in cartesian_product(set1, n-1):
rv.add((x,) + y)
return rv
如果要持之以恒原始的参数的顺序,使用rv = []
和rv.append
代替。
答
在递归调用cartesian_product(set1,prod,n-1)
内部,您正在传递列表prod,并且您又将值附加到它,所以它随着时间的推移而增长,并且内部循环从不终止。也许你可能需要改变你的实现。
当它第二次运行时,您将'prod'作为'set2'传递。由于'prod'在函数之外定义,所以set2和prod现在是相同的东西。所以当你在set2和'prod.append'中执行'for y'时,你会附加到'set2',这会导致无限次的迭代。 – algrebe
提示:['itertools.product'](https://docs.python.org/3/library/itertools.html#itertools.product)可以完成这项工作(除非这是某种作业) – JBernardo
但是循环应该当n