简体   繁体   中英

Stackless Python - Recursion in a for loop?

I'm fairly new to programming and I've been working with Python for a few months now. I'm trying to get a concept to work with Stackless, but just can't figure out how (though I've written other test scripts that work with Stackless).

Anywho, as a boiled down example consider the following code that runs through a list and finds all permutations (edit: n-dimensional cartesian products) of it by calling the same function recursively.

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]))

which yields:

['a', 'a', 'a', 'a', 'a']... [8, 8, 8, 8, 8]

So far it seems that the only examples I find with Stackless and recursion have the function sending information out at the end of the function after it's all done. Never in the middle of a for loop, as would be necessary in the above.

How the heck would I do this? How would I turn this into a script that would run with tasklets rather than recursive functions? ( This version is the best I can come up with, but it fails no matter how I arrange it. This is one of many tries, I may as well throw spaghetti up against a wall at this point.)

Bonus e-cookie for a way to do it without a bounceBack function - I haven't yet been able to find a way to have a single tasklet pass information to itself multiple times without one.

Thanks for your time!

I think you want to research "generators" (ie "yield" python keyword). Basically a generator lets you pause in the middle of a function call and sort of return the result. When the function is "called" again it resumes at the line just after the "yield". When you finally "return" you are done.

Here's some example code for you:

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

The output is below. Notice in the generator case (myGen), the "in myGen" is printed alternating with the print of the list. But in the myFn of course "in myFn" is printed out first.

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

If I've understood your question right and since you already have your method in place, plugging this in would work

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

Alternatively you could use *args / **kwargs in the parameters list to the tasklet

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM