10

In Python 2.7 I want to modify the step of a for loop in function of the specifics conditions satisfied in the loop. Something like this:

step = 1
for i in range(1, 100, step):
    if ...... :
        step = 1
        #do stuff
    else:
        step = 2
        #do other stuff

but it seems that this can't be done, step is always 1.

Thanks.

David
  • 1,155
  • 1
  • 13
  • 35

6 Answers6

20

you would need to increment step manually which can be done using a while loop. checkout difference between while and for loop.

The for statement iterates through a collection or iterable object or generator function.

The while statement simply loops until a condition is False.

if you use a while loop your code would look something like this:

step = 1
i = 1
while i < 100:
    if ...... :
        step = 1
        #do stuff
    else:
        step = 2
        #do other stuff
    i = i + step
OLIVER.KOO
  • 5,654
  • 3
  • 30
  • 62
8

np.arrange creates a (numpy) array with increasing values. The for-loop goes through all the values of the array. (Numpy is a powerful library for computations with numerical arrays)

import numpy as np
for i in np.arange(start,stop,stepwidth):
    # your stuff
bieboebap
  • 320
  • 3
  • 18
  • 2
    An explanation would help readers understand your answer. – Werner Henze Mar 08 '20 at 19:56
  • np.arrange creates a (numpy) array with increasing values. The for-loop goes through all the values in the array. (Numpy is a library that creates a normal array, but it can perform parallel actions on the array, making it much faster than python arrays) – bieboebap Mar 12 '20 at 18:58
  • Are you saying that the instructions inside this for loop would get executed parallely? What if it is not what I need ? – Haha Aug 24 '21 at 13:11
  • The code inside the loop will not be executed in parallel. What do you mean with the second question? – bieboebap Aug 25 '21 at 14:04
3

You could do it with a while loop:

step = 1
i = 1
while i < 100:
    if ...... :
        step = 1
        #do stuff
    else:
        step = 2
        #do other stuff
    i+=step
WholesomeGhost
  • 1,101
  • 2
  • 17
  • 31
2

If you want to over-complicate things, you could create a custom generator where you can use the generator.send method to pass in a new step during iteration.

def variable_step_generator(start, stop=None, step=1):
    if stop is None:
        start, stop = 0, start

    while start < stop:
        test_step = yield start

        if test_step is not None:
            step = test_step
            yield

        start += step

With usage like:

variable_step_range = variable_step_generator(1, 100)
for i in variable_step_range:
    print i
    if i == 10:
        variable_step_range.send(10)
    if i == 90:
        variable_step_range.send(1)

#  1,  2,  3,  4,  5,  6,  7,  8,  9, 
# 10, 20, 30, 40, 50, 60, 70, 80, 90, 
# 91, 92, 93, 94, 95, 96, 97, 98, 99

But this isn't really much more than a wrapper around the while loop that the other answers suggest.

Jared Goguen
  • 8,772
  • 2
  • 18
  • 36
1

The second line of your code creates a range object that is then used for the rest of the loop, and your code doesn't modify that range object. And even if you did change the step, that wouldn't change just the next element of the range, it would change the whole range object (that is, changing the step to 2 would make every element in the range 2 more than the previous). If you really want to, you can create a named object and modify it within the for loop, but that would be a rather messy thing to do.

You can also use another index separate from the main for loop one. For instance:

actual_index = 1
for for_loop_index in range(1,100):
   if condition1:
        actual_index = actual_index + 1
   if condition2:
        actual_index = actual_index + 2
   if actual_index > 99:
        break

This would basically be a while loop, except with a hard limit on the number of iterations, which could be useful in some use cases.

Acccumulation
  • 3,491
  • 1
  • 8
  • 12
  • This seems unnecessarily confusing. If you needed a separate increment, why wouldn't you just have another variable for that increment outside of a `while` loop conditioning on `actual_index` and maintain them separately? – miradulo Sep 12 '17 at 15:29
  • I've read your comment several times and still aren't sure what you're saying, so it's a bit odd that you're calling my answer "confusing". You appear to be using "separate increment" to refer to the *original* increment, and imagining (but not stating) that the while loop is inside the for loop, not explaining how your for loop would do anything, and not addressing at all my point that eschewing a while can be a safeguard if they think they might mess up and make an infinite loop. – Acccumulation Sep 13 '17 at 04:16
  • I'm sorry to hear that. It is probably then more simple to say I don't find your answer useful and leave it at that. – miradulo Sep 13 '17 at 11:44
0

You could add a skip check:

skip = 0
for i in range(1, 100):
    if skip != 0:
        skip -= 1
        continue
    if ...... :
        #do stuff
    else:
        skip = 1
        #do other stuff
sainoba
  • 158
  • 1
  • 13