【问题标题】:Stackless Python - Recursion in a for loop?Stackless Python - for 循环中的递归?
【发布时间】:2011-06-10 02:57:49
【问题描述】:

我对编程还很陌生,而且我已经使用 Python 工作了几个月了。我正在尝试获得一个与 Stackless 一起使用的概念,但就是不知道如何(尽管我已经写了 other test scripts 与 Stackless 一起使用)。

Anywho,作为一个简化的示例,考虑以下代码,该代码遍历一个列表并通过递归调用相同的函数来找到它的所有排列(编辑: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 循环的中间,就像上面所说的那样。

我该怎么做呢?我如何将它变成一个可以使用 tasklet 而不是递归函数运行的脚本? (This version 是我能想到的最好的了,但不管我怎么安排都失败了。这是许多尝试之一,我不妨把意大利面扔到墙上。)

奖励 e-cookie 用于在不使用bounceBack 功能的情况下执行此操作 - 我还没有找到一种方法让单个 tasklet 在没有一个的情况下多次将信息传递给它自己。

感谢您的宝贵时间!

【问题讨论】:

  • 我对 Stackless Python 一无所知,但我觉得我应该做一些小笔记。首先,我建议不要使用main 作为变量名。其次,这不计算排列,它计算 n 元素列表的 n 维笛卡尔积。 (5 元素列表只有 120 种排列。)第三,recursionconcurrency 根本不一样。抱歉,我无法解决您遇到的主要问题!
  • 对于使用'main',这是有道理的,我会记住的。至于笛卡尔积......我不能保证我会记住这个词,但我会尽量记住差异。递归和并发之间的差异也是如此。在自学时很难把所有的词都说对,但我会尽力而为。谢谢!

标签: python recursion concurrent-programming stackless python-stackless


【解决方案1】:

我认为您想研究“生成器”(即“yield”python 关键字)。基本上,生成器允许您在函数调用中间暂停并返回结果。当再次“调用”该函数时,它会在“yield”之后的行处恢复。当你最终“返回”时,你就完成了。

下面是一些示例代码:

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

【讨论】:

  • 我使用了生成器和产量,但我不明白这对我有什么帮助。是的,生成器可以在 yield 之后暂停,直到再次调用,但这将是问题的一部分。为了让 Stackless 再次调用同一个小任务,小任务需要处于空闲和监听位置。生成器只是暂停,并没有真正接受新的输入。
【解决方案2】:

如果我正确理解了您的问题,并且您已经有了自己的方法,那么插入它就可以了

import stackless as s
channel = s.channel()
s.tasklet(traverseList)(myList,tempList,solutionList)
s.run()
print("%s... %s" %(solutionList[0], solutionList[-1]))

或者,您可以在 tasklet 的参数列表中使用 *args / **kwargs

【讨论】:

    猜你喜欢
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 2017-12-06
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多