user1981659
user1981659

Reputation: 41

Could I use a for loop instead of a while loop?

I have a very basic question about loops. I'm trying to get into programming and am currently reading the book "Learn Python The Hard Way", and got stuck on study drill number 5 on ex 33: http://learnpythonthehardway.org/book/ex33.html

This is what my code looks like:

i = 0
numbers = []

def main(i, numbers):
    userloop = int(raw_input("Type in max value for the loop > "))
    while i < userloop:

        print "At the top i is %d" % i
        numbers.append(i)
        userincrease = int(raw_input("Increase > "))
        i += userincrease

        print "Numbers now: ", numbers
        print "At the bottom i is %d" % i


    print "The numbers: "
    print numbers
    for num in numbers:
    print num       


main(i, numbers)

The thing is that i want to use a for loop instead of the while loop. Is that even possible and then, how do I do it? I've tried simply exchanging

while i < userloop:

with

for i in range(userloop)

But then, the i value kinda resets every time it reaches the "top" of the loop.

Since I'm very much new to this, please don't be too mean if i missed something obvious.

By the way, does anyone know whether this book is any good to begin with or am I wasting my time?

Upvotes: 3

Views: 1587

Answers (5)

user3056080
user3056080

Reputation: 11

I did it using this code, where p is the argument you set in the function call numba(p)

i = 0
elements = [ ]

def numba(p):
    for i in range(0, p):
        print "At the top i is %r" % i
        elements.append(i)
        print "Numbers now: ", elements
        print "At the bottom i is %r" % (i + 1)

numba(3)

Upvotes: 1

user1922460
user1922460

Reputation:

So I checked out the question on the Python the Hard Way website that you linked to...I think he was actually just asking you to re-write his original script using a for loop and range in that case you could do something like this:

numbers = []

for i in range(6):
    print "at the top i is", i
    numbers.append(i)
    print "numbers now", numbers

print "finally numbers is:"
for num in numbers:
    print num

If you run that you'll get output like this:

$ python loops.py 
at the top i is 0
numbers now [0]
at the top i is 1
numbers now [0, 1]
at the top i is 2
numbers now [0, 1, 2]
at the top i is 3
numbers now [0, 1, 2, 3]
at the top i is 4
numbers now [0, 1, 2, 3, 4]
at the top i is 5
numbers now [0, 1, 2, 3, 4, 5]
finally numbers is:
0
1
2
3
4
5

To answer your question about the increment statement and if it is necessary, try this:

for i in range(6):
    print "at the top i is", i
    numbers.append(i)

    i += 2
    print "numbers now", numbers
    print "at the bottom i is", i

print "finally numbers is:"
for num in numbers:
    print num

And you'll get something like this as output:

$ python loops.py
at the top i is 0
numbers now [0]
at the bottom i is 2
at the top i is 1
numbers now [0, 1]
at the bottom i is 3
at the top i is 2
numbers now [0, 1, 2]
at the bottom i is 4
at the top i is 3
numbers now [0, 1, 2, 3]
at the bottom i is 5
at the top i is 4
numbers now [0, 1, 2, 3, 4]
at the bottom i is 6
at the top i is 5
numbers now [0, 1, 2, 3, 4, 5]
at the bottom i is 7
finally numbers is:
0
1
2
3
4
5

Do you see what's going on here? Remember that the range function produces a list like this:
range(6) -> [0, 1, 2, 3, 4, 5].
This is something that Python's for statement knows how to iterate over (they call these types of things iterables). Anyway, the variable i is bound to one item in range(6) (i.e. the list [0, 1, 2, 3, 4, 5]) each iteration. Even if you do something to i inside the for loop, it will be rebound to the next item in the iterable. So that increment statement is definitely not necessary. In this case it just adds 2 to whatever i is, but it is rebound like normal each iteration regardless.

Okay after all that, here is my crack at changing your specific code with the options of changing the iterator each time from using a while loop to using a for loop with range.

I think you've covered functions just by glancing at the previous chapters of the online book you linked to, but if you haven't seen recursion before it might be a little confusing. The if statement before calling the function again is to keep the current value from exceeding the value in the range, which is going to give you an error about maximum recursion depth exceeded (python does this to prevent a stack overflow error I'm pretty sure).

One final point you can do things like this with range:
range(0, 10, 2) -> [0, 2, 4, 6, 8]
which I use below:

def my_loop(max, current=0, increment=1, numbers=[]):
    for x in range(current, max, increment):
        print "at the top, current is %d" % current
        numbers.append(current)

        increment = int(raw_input("Increase > "))
        current += increment

        print "numbers is now: ", numbers
        print "at the bottom current is %d" % current
        break

    if current < max:
        my_loop(max, current, increment, numbers)
    else:
        print "no more iterating!"


max = int(raw_input("Type in max value for the loop > "))    

my_loop(max)

I don't think I would ever do it this way for real, but it's an interesting take at least.

Upvotes: 1

Grisha S
Grisha S

Reputation: 838

Well, I guess you could try digging in the direction of generators for dynamically controlled for loops

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121744

A for loop in python loops over a series of values provided by the expression after in. In Python we use the term iterable for anything that can produce such a series. That can be a range(), but it could be anything that can be iterated over (looped over). The loop variable i receives the next value on each iteration, whatever value there was before.

Thus, the following is legal:

for i in ('foo', 'bar', 'baz'):
    print i
    i = 'spam'

but the i = 'spam' essentially does nothing.

You'd have to approach it differently; skip those values instead:

print_at = 0
for i in range(userloop):
    if i >= print_at:
        print "At the top i is %d" % i
        numbers.append(i)
        userincrease = int(raw_input("Increase > "))
        print_at = i + userincrease

        print "Numbers now: ", numbers
        print "At the bottom i is %d" % i

Every time you ask the user for an increase, we update the value print_at to be the sum of the current value of i plus that increase, and then proceed to ignore most of the loop body until i catches up with print_at.

Upvotes: 4

yoozer8
yoozer8

Reputation: 7489

There is a key difference between a for loop and a while loop.

for loop: executes the loop body a fixed number of times, counting the iterations.

while loop: executes the loop body repeatedly as long as the loop's condition is true.

Typically, when starting from zero and stopping at a specific number (such as userloop) would mean a for loop is most appropriate. However, this program isn't saying "I'm going to count from 0 to userloop and do this stuff each time"; it's saying "I'm starting at zero, and I'm going to do this stuff, changing a value according to user input, until that value meets a condition (> userloop)".

The user could enter 0 a bunch of times, or enter negative numbers, and you might never come out of the loop.

Upvotes: 2

Related Questions