Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Generator Indexing Optimization

Let's say I have a generator that I want to pull the 10th element from but ignore the first 9. The generator is a function I've written that looks something like this:

def myGenerator(arg1, arg2):
    for i in arg1:
        myState = doSomeWork(i, arg2)
        yield expensiveOperation(myState)

Now I can use it and grab the 10th index out of it like this:

myGen = myGenerator(list1, list2)
tenthElement = next(itertools.islice(myGen,10,11))

I'm wondering if this runs expensiveOperation ten times, or just once? (EDIT: it calls it 10 times, but this next part is what I'm interested in.) Is there any way to optimize away the other 9 calls to expensiveOperation since they are discarded? (edited for clarity)

I can think of several other solutions that don't involve using a generator function and would give exactly what I want, but the syntax isn't as clean as just turning an iterative function into a generator by replacing return with yield.

EDIT: I'm not necessarily trying to solve this specific problem so much as looking for a way to inexpensively "scroll" a generator. In the real case I'm currently working with, I don't actually know which index I want when I call myGenerator for the first time. I may grab the 15th index, then the 27th, then the 82nd. I could probably figure a way to slice to the 15th on the first call, but then I need to scroll 12 more the next time around.

like image 241
Mike Edwards Avatar asked Dec 05 '25 10:12

Mike Edwards


1 Answers

The generator is isolated from its consumer -- it doesn't know what is being throw away. So, yes, it does the expensive operation at every step.

I would just move the expensive operation outside the generator:

def myGenerator(arg1, arg2):
    for i in arg1:
        myState = doSomeWork(i, arg2)
        yield myState

myGen = myGenerator(list1, list2)
tenthElement = expensiveOperation(next(itertools.islice(myGen,10,11)))
like image 164
Raymond Hettinger Avatar answered Dec 08 '25 02:12

Raymond Hettinger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!