Iteration using for in Python (Part 2)

Example: summing values in a list of numbers

Let's try using a for loop to add up numbers in a list.

def sum(num_list):

    for item in num_list:
        total = total + item

Expressing this as iteration is pretty straightforward: we go through each element in the list, and add it to the total.


def sum(num_list):
    total = 0
    for item in num_list:
        total = total + item

As usual, we check to make sure that any variable used in the loop body has been initialized, so we give total a value of 0.


def sum(num_list):
    total = 0
    for item in num_list:
        total = total + item
    return total

And we complete the function by returning total.


def test_sum():
    """Tests correctness of sum
    """
    assert sum([1]) == 1  
    assert sum([1, 4, 2, 3]) == 10
    assert sum([]) == 0

test_sum()

For our tests, we ensure that we have a list of length greater than one and also the empty list.


The program is run and no output is obtained. The lack of error messages tells us that our function works properly.


Example: counting specific characters in a string

As a second example, we revisit the problem of counting specific characters in a string.

def count_chars(entry, char):
    """Determines number of occurrences of 
       char in entry.

       Preconditions:
       entry: nonempty string
       char: string of length 1
    
       Parameters:
       entry: the string with character to count
       char: the character to count
 
       Returns: int, nonnegative
    """

In our docstring, we specify that char is a string of length 1.


    count = 0
    for one in entry:
        if one == char:
            count = count + 1

Again, it is straightforward to express the solution as iteration, as we consider each character in the string in turn. We check for a match, updating the count if there is a match, and ensure that count is initialized.


    return count

Finally we return count.


def test_count_chars():
    """Tests correctness of count_chars
    """
    assert count_chars("apple", "p") == 2  
    assert count_chars("apple", "d") == 0
    assert count_chars("", "d") == 0

test_count_chars()

To test the function, we have assert count_chars("apple", "p") == 2 where there is at least one match, assert count_chars("apple", "d") == 0 where there is no match, and assert count_chars("", "d") == 0 for the empty string.


Comparing use of while and for

count_chars defined using while:

def count_chars(entry, char):
    count = 0
    pos = 0
    while pos < len(entry):
        if entry[pos] == char:
            count = count + 1
        pos = pos + 1
    return count

count_chars defined using for:

def count_chars(entry, char):
    count = 0
    for one in entry:
        if one == char:
            count = count + 1
    return count

We see that the code using a for loop is simpler than the code using a while loop. That is, we don't need to initialize the counter or increment it. This reduces the length of the function by two lines of code.


Example: determining if a number is prime

As another example, how can we use iteration to determine if a number is prime?

An integer n > 1 is prime if it is the multiple of only 1 and n.

The iteration is more obvious when we think about a number not being prime.

An integer n > 1 is not prime if it is the multiple of a number in the range from 2 to n – 1.

We can iterate through numbers from 2 up to n – 1 and see if n is a multiple.

For example, to check if n equal to 5 is prime, we check if 5 is a multiple of 2, which it isn't, and if it is a multiple of 3, which it isn't, and finally if it is a multiple of 5 minus 1, or 4, which it isn't, so we conclude that 5 is prime.

To check if n equal to 9 is prime, we check possibilities going from 2 to 8. 9 is not a multiple of 2, but since it is a multiple of 3, we can conclude that 9 is not prime.


Writing the function

def is_multiple(number, factor):
    return number % factor == 0

To write a function that determines if the input is a prime number, we'll use the helper function is-multiple which we created earlier.


def is_prime(num):
    """Determines if num is prime.

       Preconditions:
       num: int > 1
    
       Parameters:
       num: number being checked
 
       Returns: Boolean (True if prime)
    """

Our docstring indicates that we are only considering inputs of size greater than 1, and that we are returning a Boolean.


    for factor in range(2, num):

We want to consider values from 2 to num - 1; since the stop value in a range is not included, we can use start and stop values of 2 and num.


        if is_multiple(num, factor):
           return False

If the input is a multiple of any of the numbers in the range, then we return False, which allows us to exit the loop early.


    return True

If we don't exit in the loop body, we return True.


def test_is_prime():
    """Tests correctness of is_prime
    """
    assert is_prime(2) == True  
    assert is_prime(3) == True
    assert is_prime(53) == True
    assert is_prime(120) == False

test_is_prime()

In our tests we ensure that we have at least one prime and at least one nonprime.