When do you use a for loop and when to use a while loop. Are there other loop types in Python? Some of the slicing examples almost look like loops.

for loops are specifically helpful for going through a string or list or tuple... the for loop executes using whatever variable you say as the current item (does that make sense?)

nums = [1,2,3,4]
for number in nums:
    print item,

Here, for each iteration the "item" variable changes...to 1, then 2, then 3, and finally 4.

If you did this with a while statement, it might look like this:

nums = [1,2,3,4]
i = 0
while i < len(nums):
    print nums[i],
    i = i + 1

Now, not only does this code (using while) longer, it's more abstract. Someone who may not understand what exactly it's doing has to walk through each iteration and understand what's happening. With the for loop, it's so much more like english that you can possibly understand it just reading it.

For and While loops serve different functions, you can actually make a For loop using a while loop (though I don't reccomend it.)

Here's a useful function for text-based games:

def ask_yes_no_question(question):
      """Asks a yes or no question for the user"""
      response = "None"
      while response not in "yn":
            response = raw_input(question).lower()
      return response
ask_yes_no_question("Would you like to play again?(y/n): ")

An example of the for loop, this one removes all vowels from your word or phrase.

word = raw_input("Please enter a word or phrase")
for letter in word:
    if letter not in "aeiouAEIOU":
        print letter

The "for loop" loops (iterates) through the items of a sequence (string, list, tuple, dictionary, set ...). The "while loop" loops until a condition is met. Though the two loops are different beasts, they can overlap in functionallity. You can break out of either loop on a conditional statement.

If you want to loop a fixed number of times, it is easier to use a "for loop" ...

for k in range(100):
   print "I should not cuss!"

Yes, there are other loops in Python. For instance a recursive function (a function that calls itself) is a loop for special purposes ...

# a recursive function to print n newlines
def new_lines(n):
  if n > 0:
    print
    new_lines(n-1)

print "-----"
new_lines(20)
print "-----"

This is of course a silly application for a recursive function, just a demo. Below is a more common application of a recursive function ...

def gcd2(x, y):
    """greatest common denominator, recursive"""
    if x > y:
        return gcd2(x-y, y)
    if x < y:
        return gcd2(x, y - x)
    if x == y:
        return x

x = 14
y = 63
print gcd2(x, y)  # 7

Interestingly the above recursive function can be replaced with a function containing a while loop and is much faster ...

def gcd3(x, y):
    """greatest common denominator, non-recursive"""
    while y:
        x, y = y, x % y
    return x

x = 14
y = 63
print gcd3(x, y)  # 7

I am digressing as usual!

I think I am getting a feeling in which case to use 'for' or 'while'. Never looked at a recursive fuction as a loop, but I guess it is and can be used for that purpose. Almost looks like a limited goto!

With the loops there is also continue, break and else. Why and how are they used in a loop?

Here is an example of continue and else ...

for k in range(10):
    # skip values > 3 or < 6
    if 3 < k < 6:
        continue
    print k,     # 0 1 2 3 6 7 8 9
else:
    # works only if there is no break statement in the loop
    print
    print "final k =", k  # final k = 9

I think I am getting a feeling in which case to use 'for' or 'while'. Never looked at a recursive fuction as a loop, but I guess it is and can be used for that purpose. Almost looks like a limited goto!

With the loops there is also continue, break and else. Why and how are they used in a loop?

It's mathematically provable that any recursive function can also be accomplished with a for loop, and vice-versa.

continue is used when you need to go back to the top of the loop. That typically happens when you've processed enough to know that it's time to start over.

break is used when it's time to exit from the loop. That should happen when you've met an exit conditions. One of my favorite idioms:

while True:  <---
   answer = raw_input("What's your answer? ")
   if is_correct(answer):
       print "You got it!"
 --> break
   else:
       print "Try again!"

This is used in cases where you are certain that you want the block inside the loop to execute at least once.

else with loops is mostly silly, AFAIK. Any code after the while or for block is called "fallthrough" and is effectively equivalent to an "else."

>>> def test(a):
    for i in range(a):
        print i,
    else:                           <--- else
        print "Empty list!"

        
>>> test(5)
0 1 2 3 4 Empty list!
>>> test(0)
Empty list!
>>> 
>>> def test2(a):
    for i in range(a):
        print i,
    print "Empty list!"        <--- fallthrough

    
>>> test2(5)
0 1 2 3 4 Empty list!
>>> test2(0)
Empty list!
>>>

Perhaps you might want to include an else just for clarity for human readers, but human readers are used to the idea of "fallthrough."

Jeff

So, if the fallthrough is due to a 'break' statement, the 'else' associated with a 'while' or 'for' will not kick in? Might be useful sometimes.

So, if the fallthrough is due to a 'break' statement, the 'else' associated with a 'while' or 'for' will not kick in? Might be useful sometimes.

Hey ... you're right about that. Sample code:

>>> def test3(a):
    for i in range(a):
        print i,
        if (i+1) % 17 == 0:
            break
    else: print "else reached!"
    print "Empty list"

    
>>> test3(5)
0 1 2 3 4 else reached!
Empty list
>>> test3(21)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Empty list
>>>

Apparently, else protects fallthrough code from break.

Hmm...now for a good way to use that behavior...

Thanks,
Jeff

Found a use in class today!

Tic-tac-toe game. Problem: we need to loop until the board is full *or* until there's a winner. If the board is full, there might be a winner (if the last move is a winning move), or there might be a tie. Solution: use an else on the loop.

board = [' ']*9  # board contains ' ', 'X', and 'O's

while ' ' in board:
   print_board()
   player_turn()
   if is_winner('X'):
      print "You won!"
      break
   
   computer_turn()
   if is_winner('O'):
      print "You lost!"
      break

else:
   print "A tie!"

print "\nFinal board:\n"
print_board()

This works because the break will skip over the else; hence, fallthrough to the else is guaranteed to be a tie.

:cool:

Jeff

That looks interesting! Would you mind posting your entire tic-tac-toe program?

This was my home version; the one at school is a bit different and profited more directly from the else at the end of the loop; I just threw it in here for illustration.

The functions isint() and get_valid_int() were also intended for my students, who haven't learned 'try' yet.

# tictactoe
# 2006.11.03

# imports

import random

# Functions

def print_board(board):
    """
print_board(board) --> None

prints board.
"""

    print ' | '.join(board[:3])
    print '-'*9
    print ' | '.join(board[3:6])
    print '-'*9
    print ' | '.join(board[6:])

    print

def isint(s):
    """
isint(s) --> Bool

Returns True if s can be converted into an integer.
"""

    if s.startswith('-'):
        return isint(s[1:])
    else:
        return s.isdigit()
    
def get_valid_int(prompt, Min = None, Max = None):
    """
get_valid_int(prompt, Min, Max) --> int

Prints prompt and returns an integer in [Min,Max].
"""

    if Min > Max:
        Min, Max = Max, Min
        
    while True:
        s = raw_input(prompt)
        if isint(s):
            s = int(s)
        else:
            print "Enter an integer, please"
            continue
        if Min and s < Min:
            print "Must be at least %d" % (Min)
            continue
        if Max and s > Max:
            print "Must be at most %d" % (Max)
            continue
        return s

def get_valid_moves(board):
    """
get_valid_moves(board) --> list

Returns list of empty squares on board.
"""
    return [x for x in range(len(board)) if board[x] == ' ']

def player_turn(board):
    """
player_turn(board) --> board

Gets players (valid) move and returns new board with move taken.
"""
    
    valid_moves = get_valid_moves(board)
    new_board = board[:]
    
    print valid_moves
    while True:
        move = get_valid_int("Enter a square number to play in: ",0,8)
        if move in valid_moves:
            new_board[move] = 'X'
            return new_board
        else:
            print "That square is filled!"

def computer_turn(board):
    """
computer_turn(board) --> board

Gets computer's move and returns new board with move taken.
"""
    
    valid_moves = get_valid_moves(board)
    new_board = board[:]

    if not valid_moves:
        return board
    
    move = random.choice(valid_moves)
    new_board[move] = 'O'
    print "The computer chooses square %d" % (move)
    return new_board
            
def is_winner(board, player, combos):
    """
is_winner(board,player,combos) --> winner

Returns player token if player is a winner; else returns ""
"""

    for i in combos:
        l = [board[j] for j in i]
        if l == [player,player,player]:
            return player
    return ""
    
# Main

board = [' ']*9
winner = ''
winning_combos = [[0,1,2],[3,4,5],[6,7,8], \
                  [0,3,6],[1,4,7],[2,5,8], \
                  [0,4,8],[2,4,6]]

while ' ' in board:

    print_board(board)
    board = player_turn(board)
    winner = is_winner(board, 'X', winning_combos)
    if winner:
        break

    print_board(board)
    board = computer_turn(board)
    winner = is_winner(board, 'O', winning_combos)
    if winner:
        break
else:
    winner = None
    
print "\n\nThe Decision\n"
print_board(board)

if winner:
    print "%s Wins!" % winner
else:
    print "A Tie!"

Hi,

Loops are particularly useful for vocabualry. The limits are endless and I use Loops to distinguish between consonants and vowles.

Regards.

This question has already been answered. Start a new discussion instead.