5

Possible Duplicate:
How to clone a Python generator object?

Suppose I have a generator 'stuff_to_try', I can try them one by one but if I had a method that wanted to go through the generator and that method is recursive, I want to let each recursion get a fresh new generator that starts at the first yield rather than where the last recursion left off.

def solve(something):
    if exit_condition(something):
        return

    next_to_try = stuff_to_try.next()
    while not if_works(next_to_try):
        next_to_try = stuff_to_try.next()
    solve(do_something(something))

Of course I can define stuff_to_try inside the recursive function but is there a better way? Is there an equivalent of stuff_to_try.clone().reset() or something?

Community
  • 1
  • 1
xster
  • 6,269
  • 9
  • 55
  • 60

2 Answers2

3

Define the generator in a function:

def stuff_to_try():
    return (i for i in [stuff, to, try])

Then each time you want a new generator, just call the function.

def solve(something):
    if exit_condition(something):
        return

    for next_to_try in stuff_to_try():
        if_works(next_to_try):
            break
    solve(do_something(something))

If I read your question correctly, what you actually want is this:

def solve(something):
    if exit_condition(something):
        return

    for each in [stuff, to, try]:
        if_works(each):
            break
    solve(do_something(something))
Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
1

The simplest answer is make it a list, then it will have the behaviour you want:

stuff_to_try = [i for i in [stuff, to, try]]

Any efficiency gains from being lazy are likely to be lost by recalculating the values again and again.

Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
  • 1
    oops, bad example in the question. The list would be easier since I'm implying that there's a short finite list to generate but the real question is how to clone generators so suppose the generator is more complicated – xster Dec 15 '12 at 23:25
  • 2
    Definitely the simplest, but sometimes not practical. A list might not fit in memory. – Mark Ransom Dec 16 '12 at 01:23
  • Of course, that's the downside. That said, it may be the only practical solution depending on the generator at hand. – Gareth Latty Dec 16 '12 at 01:26
  • why not `stuff_to_try = (i for i in [stuff, to, try])`? – endolith Oct 27 '13 at 14:47