Stackless Python - рекурсия в цикле for? - PullRequest
3 голосов
/ 10 июня 2011

Я довольно новичок в программировании и уже несколько месяцев работаю с Python.Я пытаюсь заставить концепцию работать со Stackless, но не могу понять, как (хотя я написал другие тестовые сценарии , которые работают со 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, как было бы необходимо в приведенном выше.

Как, черт возьми, я бы это сделал?Как бы превратить это в скрипт, который будет работать с тасклетами, а не с рекурсивными функциями?( Эта версия - лучшее, что я могу придумать, но она не сработает, независимо от того, как я ее устрою. Это одна из многих попыток, на этом этапе я могу также бросить спагетти в стену.)

Бонус e-cookie за способ сделать это без функции bounceBack - я пока не смог найти способ, чтобы один тасклет передавал информацию себе несколько раз без одного.

Спасибо за ваше время!

Ответы [ 2 ]

1 голос
/ 21 июня 2011

Я думаю, что вы хотите исследовать "генераторы" (то есть "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, конечно, сначала печатается «в 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
0 голосов
/ 25 июля 2011

Если я правильно понял ваш вопрос, и поскольку у вас уже есть свой метод, его подключение будет работать

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

В качестве альтернативы вы можете использовать * args / ** kwargs в списке параметровтасклет

...