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.