Week 12

Simplified For Loops and more Nested Lists

Author:Christopher Haynes
Email:chaynes@indiana.edu
Affiliation:Indiana University
Course:BL CSCI A201
Date:2008-04-03
Copyright © 2008, Christopher Haynes—all rights reserved.

Demo: list ordering, sorting, and reversing

>>> [1, 'z'] < [2, 'a']
True
>>> [2, 'z'] < [2, 'a']
False
>>> table = [[2, 'z'], [2, 'a'], [1, 'b']]
>>> table.sort()
>>> table
[[1, 'b'], [2, 'a'], [2, 'z']]
>>> table.reverse()
>>> table
[[2, 'z'], [2, 'a'], [1, 'b']]
>>> table[0:2]
[[2, 'z'], [2, 'a']]
>>>

Demo concepts

FYI: Pretty printing

Review: Common loop patterns

Common loop patterns (continued)

Example of while loop and equivalent for loop

def extend_list(lst1, lst2):
    index = 0
    while index < len(lst2):
        lst1.append(lst2[index])
        index = index + 1

def extend_list(lst1, lst2):
    for index in range(len(lst2)):
        lst1.append(lst2[index])

For loop syntax and semantics

For loop translation to a while loop

A for loop of the form

for variable in range( expression ):
block

is equivalent to the while loop (provided index is not used after the loop and stop is not used anywhere else):

variable = 0
stop = expression
while variable < stop :
block
index = index + 1

Using simplified for loops

Exercise: for_sum

def for_sum(lst):
    answer = 0
    for index in range(len(lst)):
        answer = answer + lst[index]
    return answer

Answer: while_sum

def while_sum(lst):
    answer = 0
    index = 0
    while index < len(lst):
        answer = answer + lst[index]
        index = index + 1
    return answer

clicker After the following definition, what does max_value1([1, 20, 8]) do?

def max_value1(list_of_numbers)
    index = 0
    while index < len(list_of_numbers)
        value = list_of_numbers(index)
        if value < answer
            answer = value
        return answer
  1. Syntax error
  2. Runtime error message
  3. Returns 20
  4. Returns 1
  5. None of the above

Answer: A

clicker After the following definition, what does max_value2([1, 20, 8]) do?

def max_value2(list_of_numbers): # colon added
    index = 0
    while index < len(list_of_numbers): # colon added
        value = list_of_numbers(index)
        if value < answer: # colon added
            answer = value
        return answer
  1. Syntax error
  2. Runtime error message
  3. Returns 20
  4. Returns 1
  5. None of the above

Answer: B (fourth line)

clicker After the following definition, what does max_value3([1, 20, 8]) do?

def max_value3(list_of_numbers):
    index = 0
    while index < len(list_of_numbers):
        value = list_of_numbers[index] # [...] not (...)
        if value < answer:
            answer = value
        return answer
  1. Syntax error
  2. Runtime error message
  3. Returns 20
  4. Returns 1
  5. None of the above

Answer: B (fifth line: undefined variable)

clicker After the following definition, what does max_value4([1, 20, 8]) do?

def max_value4(list_of_numbers):
    answer = list_of_numbers[0] # new line
    index = 0
    while index < len(list_of_numbers):
        value = list_of_numbers[index]
        if value < answer:
            answer = value
        return answer
  1. Syntax error
  2. Runtime error message
  3. Returns 20
  4. Returns 1
  5. None of the above

Answer: D

clicker After the following definition, what does max_value5([1, 20, 8]) do?

def max_value5(list_of_numbers):
    answer = list_of_numbers[0]
    index = 0
    while index < len(list_of_numbers):
        value = list_of_numbers[index]
        if value < answer:
            answer = value
    return answer # changed indentation
  1. Syntax error
  2. Runtime error
  3. Returns 20
  4. Returns 1
  5. None of the above

Answer: E (infinite loop)

clicker After the following definition, what does max_value6([1, 20, 8]) do?

def max_value6(list_of_numbers):
    answer = list_of_numbers[0]
    index = 0
    while index < len(list_of_numbers):
        value = list_of_numbers[index]
        if value < answer:
            answer = value
        index = index + 1 # new line
    return answer
  1. Syntax error
  2. Runtime error
  3. Returns 20
  4. Returns 1
  5. None of the above

Answer: D

clicker After the following definition, what does max_value7([1, 20, 8]) do?

def max_value7(list_of_numbers):
    answer = list_of_numbers[0]
    index = 0
    while index < len(list_of_numbers):
        value = list_of_numbers[index]
        if value > answer: # changed < to >
            answer = value
        index = index + 1
    return answer
  1. Syntax error
  2. Runtime error
  3. Returns 20
  4. Returns 1
  5. None of the above

Answer: C (it works!)

Warning: it is very dangerous to add or delete elements from a list while you are iterating over it!

Consider this attempt to delete every other element from a list:

def bad_remove_blanks(los):
    """Remove from the given list of strings all elements containing
    blank (whitespace-only) strings.
    >>> los = ['spam', ' ', '\n', 'eggs']
    >>> bad_remove_blanks(los)
    >>> los # right answer is ['spam', 'eggs']
    ['spam', '\n', 'eggs']
    >>>
    """
    index = 0
    while index < len(los):
        if los[index].strip() == '':
            del los[index]
        index = index + 1

remove_blank done right

def remove_blanks(los):
    """Remove from the given list of strings all elements containing
    blank (whitespace-only) strings.
    >>> los = ['spam', ' ', '\n', 'eggs']
    >>> remove_blanks(los)
    >>> los
    ['spam', 'eggs']
    >>>
    """
    index = len(los) - 1
    while index >= 0:
        if los[index].strip() == '':
            del los[index]
        index = index - 1

Exercise: print_list

def print_list(lst):
    """Prints the elements of lst, one per line.
    >>> print_list([1, 2])
    1
    2
    >>>
    """
    index = 0
    #...
        #...
        index = index + 1

Solution: print_list

def print_list(lst):
    """Prints the elements of lst, one per line.
    >>> print_list([1, 2])
    1
    2
    >>>
    """
    index = 0
    while index < len(lst):
        print lst[index]
        index = index + 1

Exercise: multiply_list

def multiply_list(lst):
    """Takes a list of numbers and returns their product.
    >>> multiply_list([1, 2, 3])
    6
    >>>
    """
    # Hint; accumulating index loop pattern
    #...
    index = 0
    while index < len(lst):
        #...
        index = index + 1
    #...

Solution: multiply_list

def multiply_list(lst):
    """Takes a list of numbers and returns their product.
    >>> multiply_list([1, 2, 3])
    6
    >>>
    """
    # Hint; accumulating index loop pattern
    answer = 1
    index = 0
    while index < len(lst):
        answer = answer * lst[index]
        index = index + 1
    return answer

Exercise: concatenate_list

def concatenate_list(lst):
    """Takes a list of strings and returns their concatenation
    >>> concatenate_list(['spam', ' ', 'eggs'])
    'spam eggs'
    >>>
    """
    #...
    index = 0
    while index < len(lst):
        #...
        index = index + 1
    #...

Solution: concatenate_list

def concatenate_list(lst):
    """Takes a list of strings and returns their concatenation
    >>> concatenate_list(['spam', ' ', 'eggs'])
    'spam eggs'
    >>>
    """
    answer = ''
    index = 0
    while index < len(lst):
        answer = answer + lst[index]
        index = index + 1
    return answer

Exercise: concatenate_not_blank

def concatenate_not_blank(lst):
    """Takes a list of strings and returns the concatenation
    of the non-whitespace elements.
    >>> concatenate_not_blank(['spam', ' ', 'eggs'])
    'spameggs'
    >>>
    """
    # Hint: a string is blank if the string strip() method
    # returns the empty string.
    answer = ''
    index = 0
    while index < len(lst):
        #...
            #...
        index = index + 1
    return answer

Solution: concatenate_not_blank

def concatenate_not_blank(lst):
    """Takes a list of strings and returns the concatenation
    of the non-whitespace elements.
    >>> concatenate_not_blank(['spam', ' ', 'eggs'])
    'spameggs'
    >>>
    """
    # Hint: a string is blank if the string strip() method
    # returns the empty string.
    answer = ''
    index = 0
    while index < len(lst):
        if lst[index].strip() != '':
            answer = answer + lst[index]
        index = index + 1
    return answer