I would like to get only the desired iteration without having to generate from
start to the necessary point
If you need this, then you don’t need a loop, or generators, or anything - just a coordinate transformation for your coordinate system - which, given a scale s
is to basically sum an offset of s/2, and increases s in s:
def center(i, j, s=50):
return s // 2 + i * s, s // 2 + j * s
And, unless the generator relies on either a side effect done at each step (for example, reading one or more lines from a file), or a cumulative effect at each step (for example, going through a vector and adding up the accumulated values), you will always be able to go straight to the desired point, just doing the math.
For cases where previous steps are needed, then steps are needed - the function itertools.islice
can provide a shorter way to traverse all the required points of a generator before the desired point - but it doesn’t make it any easier to understand who is looking.
For example, for the generator:
def acumulador(n):
valor = 0
for i in range(0, n):
valor += i
yield valor
If I want to print only the values between 6 and 8 of the iteration I can do:
from itertools import islice
for i in islice(acumulador(10), 6, 8):
print(i)
But note that the islice
there is no way to "guess" what the iterator does at each step - the only thing it does is select the values requested in the call, but internally all the values of the accumulator are used, until you arrive at the seventh interaction (which has index 6) - there, instead of discarding the value, he does yield
of it, and the value is used in for
external.
Reiterating then: to be able to go straight to a value of the loop has nothing to do with the possibilities of the programming language, but rather with the simple logic: or the value Depends on the previous results to be calculated, and if it depends, you have to go through all the interactions, you have nothing to do (the language even has the islice precisely to "hide" the interactions that are not necessary), or, as in the example of the question, the value is independent of the calculations of the previous values in the interaction, and only depends on the numerical variables: in this case, just do this, the direct account without any tie.
I get it. The mathematical solution is always more efficient. So, just to put an end to this, in the case that I have two nested loops use the islice to get the values of example (center(0.0) and center(6.3)) would it look like? In the case as would the arguments for the call.
– Dagdeloo
The "islice" would not be appropriate in this case (see that its center function does nothing, the islice would be direct to the
centerGenerator
- but you want to find a solution that depends on two parameters, and theislice
simply call the generator sequentially, until you reach the desired position.– jsbueno
So, if we were to insist on doing this, we can, knowing that in this particular case, the width of each line is "8" - then we transform i and j into the linear position before calling the islice, and use the call
next
to recover the first value released by the islice:next(islice(centerGenerator(), i * 8 + j, i * 8 + j + 1))
– jsbueno
Actually, this one looks more like the use case for a class than for generators - you create a class, which has as parameters the scale and possibly the size of your grid (in case 8 x 8), and put methods and properties to convert the coordinates into pixels (I suppose) for the internal coordinates, and iterate all pixel coordinates if applicable.
– jsbueno
Right. The biggest interest is to know if it is possible to obtain only the umpteenth value of the iteration of a nested loop or loop. Without having to generate all the values until that iteration. I think I read somewhere about generators and iterators and I got that possibility in my mind. I just picked up a comparison of an old checkers script to try to implement this.
– Dagdeloo
(I passed this reply to the comment to the last paragraph in the same reply)
– jsbueno