Python 3.6

Impacting The Loop Counter From Within The Loop in Python

Stackoverflow question about this resulted in a detailed discussion on this topic. To summarize:

  • In other programming languages, the counter used to imcrement loops can get changed within the loops
    • this is true regardless of whether the loop is a for or a while loop

In Python: If you need to modify the counter from within the loop before incrementing to the next number in the series that controls the loop, you should use a while loop. If the loop will increment a set number of times and you do not need to modify the counter (you will just repeat some action or actions x times), then a for loop is a good choice.

Code samples that follow illustrate the compexities of trying to defy this simple guideline.


In [2]:
def jumpable_range(start, stop):
    i = start
    while i <= stop:
        j = yield i
        i = i + 1 if j is None else j

In [3]:
R = jumpable_range(2, 10)
for i in R:
    if i==5:
        i = R.send(8)
    print(i)


2
3
4
8
9
10

In [11]:
## so how to integrate into original code:
endRw=5
lenDF=97   # 1160

Q = jumpable_range(0,lenDF)
for i in Q:
    print("i: ", i)
    endIndx = i + endRw
    if endIndx > lenDF:
                endIndx = lenDF
            
    if i == endIndx: break

    print("Range to use: ", i, ":", endIndx)
    # this line is a mockup for an index that is built and used
    # in the real code to do something to a pandas DF

    i = Q.send(endIndx-1)
    print("i at end of loop", i)


i:  0
Range to use:  0 : 5
i at end of loop 4
i:  5
Range to use:  5 : 10
i at end of loop 9
i:  10
Range to use:  10 : 15
i at end of loop 14
i:  15
Range to use:  15 : 20
i at end of loop 19
i:  20
Range to use:  20 : 25
i at end of loop 24
i:  25
Range to use:  25 : 30
i at end of loop 29
i:  30
Range to use:  30 : 35
i at end of loop 34
i:  35
Range to use:  35 : 40
i at end of loop 39
i:  40
Range to use:  40 : 45
i at end of loop 44
i:  45
Range to use:  45 : 50
i at end of loop 49
i:  50
Range to use:  50 : 55
i at end of loop 54
i:  55
Range to use:  55 : 60
i at end of loop 59
i:  60
Range to use:  60 : 65
i at end of loop 64
i:  65
Range to use:  65 : 70
i at end of loop 69
i:  70
Range to use:  70 : 75
i at end of loop 74
i:  75
Range to use:  75 : 80
i at end of loop 79
i:  80
Range to use:  80 : 85
i at end of loop 84
i:  85
Range to use:  85 : 90
i at end of loop 89
i:  90
Range to use:  90 : 95
i at end of loop 94
i:  95
Range to use:  95 : 97
i at end of loop 96
i:  97

In [10]:
endRw=5
lenDF=97   # 1160
i = 0
while i < lenDF:
    print("i: ", i)
    endIndx = i + endRw
    if endIndx > lenDF:
                endIndx = lenDF

    print("Range to use: ", i, ":", endIndx)
    # this line is a mockup for an index that is built and used
    # in the real code to do something to a pandas DF

    i = endIndx
    print("i at end of loop: ", i)


i:  0
Range to use:  0 : 5
i at end of loop:  5
i:  5
Range to use:  5 : 10
i at end of loop:  10
i:  10
Range to use:  10 : 15
i at end of loop:  15
i:  15
Range to use:  15 : 20
i at end of loop:  20
i:  20
Range to use:  20 : 25
i at end of loop:  25
i:  25
Range to use:  25 : 30
i at end of loop:  30
i:  30
Range to use:  30 : 35
i at end of loop:  35
i:  35
Range to use:  35 : 40
i at end of loop:  40
i:  40
Range to use:  40 : 45
i at end of loop:  45
i:  45
Range to use:  45 : 50
i at end of loop:  50
i:  50
Range to use:  50 : 55
i at end of loop:  55
i:  55
Range to use:  55 : 60
i at end of loop:  60
i:  60
Range to use:  60 : 65
i at end of loop:  65
i:  65
Range to use:  65 : 70
i at end of loop:  70
i:  70
Range to use:  70 : 75
i at end of loop:  75
i:  75
Range to use:  75 : 80
i at end of loop:  80
i:  80
Range to use:  80 : 85
i at end of loop:  85
i:  85
Range to use:  85 : 90
i at end of loop:  90
i:  90
Range to use:  90 : 95
i at end of loop:  95
i:  95
Range to use:  95 : 97
i at end of loop:  97

In [9]:
endRw=5
lenDF=97   # 1160

for i in range(0, lenDF, endRw):
    my_range = min(endRw, lenDF-i)
    print("Range to use: ", i, ":", i+my_range)


Range to use:  0 : 5
Range to use:  5 : 10
Range to use:  10 : 15
Range to use:  15 : 20
Range to use:  20 : 25
Range to use:  25 : 30
Range to use:  30 : 35
Range to use:  35 : 40
Range to use:  40 : 45
Range to use:  45 : 50
Range to use:  50 : 55
Range to use:  55 : 60
Range to use:  60 : 65
Range to use:  65 : 70
Range to use:  70 : 75
Range to use:  75 : 80
Range to use:  80 : 85
Range to use:  85 : 90
Range to use:  90 : 95
Range to use:  95 : 97

In [1]:
endRw=5
lenDF=97   # 1160

for i in range(0, lenDF, endRw):
    endIndx = min(i+endRw, lenDF)
    print("Range to use: ", i, ":", endIndx)


Range to use:  0 : 5
Range to use:  5 : 10
Range to use:  10 : 15
Range to use:  15 : 20
Range to use:  20 : 25
Range to use:  25 : 30
Range to use:  30 : 35
Range to use:  35 : 40
Range to use:  40 : 45
Range to use:  45 : 50
Range to use:  50 : 55
Range to use:  55 : 60
Range to use:  60 : 65
Range to use:  65 : 70
Range to use:  70 : 75
Range to use:  75 : 80
Range to use:  80 : 85
Range to use:  85 : 90
Range to use:  90 : 95
Range to use:  95 : 97

In [ ]: