无栈Python - 在for循环中使用递归?
我刚开始接触编程,已经用Python写了几个月的代码。现在我想用Stackless这个库来实现一个概念,但就是搞不定(虽然我写了其他测试脚本,它们在Stackless下能正常工作)。
简单来说,下面这段代码是用来遍历一个列表,找到它的所有排列组合(编辑:n维笛卡尔积),通过递归调用同一个函数来实现。
def traverseList(theList,temp,solutions,level=1):
if level != len(theList):
for x in theList:
temp.append(x)
traverseList(theList,temp,solutions,level+1)
temp.pop()
else:
for x in theList:
temp.append(x)
solutions.append(temp[:])
temp.pop()
myList = ["a",None,2,"gamma",8] #the list doesn't always have just numbers
solutionList = []
tempList = []
traverseList(myList,tempList,solutionList)
print("%s... %s" %(solutionList[0], solutionList[-1]))
运行结果是:
['a', 'a', 'a', 'a', 'a']... [8, 8, 8, 8, 8]
到目前为止,我发现的关于Stackless和递归的例子,函数都是在最后完成后才输出信息。并没有在for循环的中间输出,这在上面的例子中是需要的。
那我该怎么做呢?我该如何把这个变成一个用任务(tasklets)而不是递归函数来运行的脚本?(这个版本是我能想到的最好方案,但无论我怎么安排它都失败。这只是我尝试的众多方法之一,现在感觉就像是在墙上扔意大利面一样。)
如果能找到一种方法,让一个任务在不使用bounceBack函数的情况下多次传递信息,那就更好了——我还没找到办法让一个任务自己多次传递信息,而不需要这个函数。
谢谢你的时间!
2 个回答
0
如果我理解你的问题没错,而且你已经有了自己的方法,那么把这个放进去就可以用了。
import stackless as s
channel = s.channel()
s.tasklet(traverseList)(myList,tempList,solutionList)
s.run()
print("%s... %s" %(solutionList[0], solutionList[-1]))
另外,你也可以在任务的参数列表中使用 *args 和 **kwargs。
1
我觉得你可以研究一下“生成器”(也就是Python中的“yield”关键字)。简单来说,生成器让你在函数执行到一半的时候可以暂停,并返回一个结果。当你再次“调用”这个函数时,它会从“yield”之后的那一行继续执行。最后,当你用“return”结束时,整个过程就完成了。
这里有一些示例代码供你参考:
def myGen(*x):
for elem in x:
print "in myGen"
yield elem
def myFn(*x):
ret = []
for elem in x:
print "in myFn"
ret.append(x)
return x
for e in myGen(1,2,3,4,5):
print e
for e in myFn(1,2,3,4,5):
print e
下面是输出结果。注意在生成器的情况下(myGen),输出“in myGen”和列表的打印是交替进行的。而在myFn中,“in myFn”则是先打印出来的。
in myGen
1
in myGen
2
in myGen
3
in myGen
4
in myGen
5
in myFn
in myFn
in myFn
in myFn
in myFn
1
2
3
4
5