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.
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)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With