Home > Net >  How can I manually progress an iterator variable in Python 3?
How can I manually progress an iterator variable in Python 3?

Time:03-28

I would like to know how to manually progress an iterator variable in Python3. In C, for example, if during a for loop such as:

for( int i = 0, k = 10; i < k; i), I could skip loop iterations when i == {2,3,4} by simply setting i from within the loop body like this: if(i == 1) i = 5;

However, when I do something like this from within a for in loop in Python3, the for in loop actually enforces that I cannot do this - it mutates i and sets it to the next sequential number regardless of what I did to the iterator variable in the loop body.

For example in the Python3 code below, I am trying to progress i to the position of j such that I can skip i to the end of the group of spaces once the algorithm has detected a group of spaces:

testString = "This is a   testzstring"
# find length and end of each space group
spacePositionsAndLengths = {}
j = 0
length = len(testString)
for i in range(length):
    if testString[i] == " ":
        j = i # mark beginning of spaces
        while j < length and testString[j] == " ":
            j  = 1
        # j-1 is now the last space. Alternatively, j is at first non-space
        lengthOfSpaces = j-i
        print(f"i: {i}\t lengthOfSpaces: {lengthOfSpaces}")
        spacePositionsAndLengths[i] = lengthOfSpaces
        i = j # remember, at this point j is at first non-space

print(testString)

That algorithm prints this output when run with:

i: 4     lengthOfSpaces: 1
i: 7     lengthOfSpaces: 1
i: 9     lengthOfSpaces: 3
i: 10    lengthOfSpaces: 2
i: 11    lengthOfSpaces: 1
This is a   testzstring

This is decent, but what I want is it to print this:

i: 4     lengthOfSpaces: 1
i: 7     lengthOfSpaces: 1
i: 9     lengthOfSpaces: 3
This is a   testzstring

I do not want the redundant 3..2..1 "countdown" style space counting.

Note: I am not building a production application; I am working on algorithms and the instructions require me to NOT use many of the builtin string methods. I note this because I expect comments saying "Why don't you just use X, Y, or Z builtin function and be done with this whole thing in 1 line??"

CodePudding user response:

To manually progress the iterator, you need access to it. You can explicitly create the iterator yourself and then both give it to the for statement and treat it yourself as you wish. Example:

irange = iter(range(10))
for i in irange:
    print(i)
    next(irange)

Output:

0
2
4
6
8

Though in your example, a while loop might be better.

CodePudding user response:

What you need is a while loop so that you can have your own iterator that you can mutate. It may look something like.

j = 0
i = 0
length = len(testString)
while i < length:
    if testString[i] == " ":
        j = i # mark beginning of spaces
        while j < length and testString[j] == " ":
            j  = 1
        # j-1 is now the last space. Alternatively, j is at first non-space
        lengthOfSpaces = j-i
        print(f"i: {i}\t lengthOfSpaces: {lengthOfSpaces}")
        spacePositionsAndLengths[i] = lengthOfSpaces
        i = j # remember, at this point j is at first non-space
     i  = 1
  • Related