11

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.

1
  • 4
    You can re-write as a while and increment step manually... Commented Sep 12, 2017 at 15:02

6 Answers 6

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
Sign up to request clarification or add additional context in comments.

Comments

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

4 Comments

An explanation would help readers understand your answer.
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)
Are you saying that the instructions inside this for loop would get executed parallely? What if it is not what I need ?
The code inside the loop will not be executed in parallel. What do you mean with the second question?
4

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

Comments

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.

Comments

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.

3 Comments

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?
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.
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.
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

1 Comment

It is less readable than the while loop, so I would not do it like this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.