无栈Python - 在for循环中使用递归?

3 投票
2 回答
2126 浏览
提问于 2025-04-16 19:17

我刚开始接触编程,已经用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

撰写回答