MC34
MC34

Reputation: 23

Looping through a list using a random range with Python

I'm quite new to Python so please excuse me if this question is very basic but I have tried searching and haven't found a way to implement something like this yet.

I am looping through a range of two numbers using a random step, and printing out some information about them. Here is my code so far:

from random import randint

#generate random number between 200 and 400
step = randint(200,400)
num = 0

for x in range(440000,450000,step):
    num = num + 1
    print("{}: {}km, increased by {}km".format(num,x,step))

I wish to be able to print out the step variable and have it change (randomly) for each iteration of the loop, however the code is only giving me one value repeating itself for each iteration. Here's an example output:

1: 440000km, increased by 274km
2: 440274km, increased by 274km
3: 440548km, increased by 274km
4: 440822km, increased by 274km
5: 441096km, increased by 274km
6: 441370km, increased by 274km
7: 441644km, increased by 274km
8: 441918km, increased by 274km
9: 442192km, increased by 274km
10: 442466km, increased by 274km
11: 442740km, increased by 274km
12: 443014km, increased by 274km
13: 443288km, increased by 274km
14: 443562km, increased by 274km
15: 443836km, increased by 274km
16: 444110km, increased by 274km

How would I go about making my loop truly random? Any and all help would be appreciated.

Thanks!

Upvotes: 2

Views: 220

Answers (3)

Duncan
Duncan

Reputation: 95622

In Python when you want to do something a bit complicated in a for loop it is often worth extracting the complicated part out into a generator.

from random import randint

def randstep(start, end, stepmin, stepmax):
    current = start
    yield current, 0
    while current < end:
        step = randint(stepmin, stepmax)
        current += step
        if current < end:
            yield current, step

for num, (x, step) in enumerate(randstep(44000, 45000, 200, 400)):
    print("{}: {}km, increased by {}km".format(num,x,step))

$ python3 t.py
0: 44000km, increased by 0km
1: 44338km, increased by 338km
2: 44587km, increased by 249km
3: 44954km, increased by 367km
$ python3 t.py
0: 44000km, increased by 0km
1: 44374km, increased by 374km
2: 44598km, increased by 224km
3: 44815km, increased by 217km

So for the actual loop you need to use while, but you can extract the looping out into a generator randstep which can then be used in a for loop. You also wanted a counter num and there is already a generator enumerate for that so no need to do num = num + 1.

Upvotes: 0

ParvBanks
ParvBanks

Reputation: 1436

This is because you are defining step ahead of calculation and it is calculated only once. Your code gives you a fixed step value of 274 each time the loop is executed.

For loop is not ideal in this case (though someone may provide a solution). You can use while loop in this case to get the desired result.

start = 440000 # this will be the starting km
num = 1        # Counter

while start <= 450000: # End value is 450000 km
    step = randint(200,400)       # This calls a new random int for each loop
    print ("{}: {}km, increased by {}km".format(num,start,step))
    start = start + step          # add start and step to give new start km
    num = num + 1                 # increment counter

Upvotes: 0

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140148

you cannot do that with a for loop since range takes the initial step (a confusion often arises from that because of C/C++ for loop legacy where it's possible to modify the step or the current index within the loop).

I'd go with a classic while loop:

from random import randint

#generate random number between 200 and 400
num = 0

x = 440000

while True:
    num += 1
    step = randint(200,400)
    x += step
    if x >= 450000:
        break
    print("{}: {}km, increased by {}km".format(num,x,step))

result:

1: 440380km, increased by 380km
2: 440586km, increased by 206km
3: 440975km, increased by 389km
4: 441221km, increased by 246km
5: 441545km, increased by 324km
6: 441803km, increased by 258km
7: 442080km, increased by 277km
8: 442476km, increased by 396km
9: 442822km, increased by 346km
10: 443179km, increased by 357km
11: 443536km, increased by 357km
12: 443779km, increased by 243km
13: 444170km, increased by 391km
14: 444449km, increased by 279km
15: 444791km, increased by 342km
16: 445023km, increased by 232km
...
28: 449154km, increased by 348km
29: 449431km, increased by 277km
30: 449647km, increased by 216km
31: 449890km, increased by 243km

I wasn't sure of the limit check so I refrained from doing while x < 450000, instead, I used an infinite loop so I can add & check afterwards (else, I feel I'm not going to be able to "emulate" the for loop.

Upvotes: 3

Related Questions