Python for loop

Introduction

Any computer algorithm requires two control flow structures: iteration and selection. Our topic today is mainly about iteration using the Python for loop. The goal of this post is to achieve three objectives:

  • Provide a beginner introduction to the for loop control structure
  • Include example code snippets for copy and paste lovers
  • Cover some tricks for advanced users.

We will start with the second objective above as we do not want our copy paste friends to wait longer. If you are a beginner or advanced user you can skip to the next section.

Code Snippets

The following code snippets demonstrate the use of for loop in Python to iterate through common data structures. You may use it as a reference or copy and paste it into your own scripts if you wish.

List of numbers

numbers = [1, 2, 3, 4, 5]
for num in numbers:
     print "Current number is %d" % num

For loop in a string

str = "Python is fun"
for char in str:
    print "Current character is %c " % char

For loop in a list of strings

planets = ['earth', 'mars', 'pluto']
for planet in planets:
     print "Current planet is %s" % planet

For loop in a tuple

countries = ('USA', 'Italy', 'France')
for country in countries:
    print "Current country is %s" % country

For loop in a mixed list

Mixed = [1, 'Me', 2, 'You', 3, 'Them']
for item in Mixed:
    print "Current item is %r" % item

For loop in a list of lists

lol = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]]
for list in lol:
    for item in list:
        print item

Range function

# Numbers from 0 to 6
for i in range(7):
     print(i)

# Numbers from 4 to 6
for i in range(4, 7):
     print(i)

# Numbers 1, 3, 5
for i in range(1, 7, 2):
     print(i)

For loop in a backward range (reverse order)

# Numbers 0, -2, -4, -6
for i in range(0, -7, -2):
     print(i)

Loop index

list = [1, 2, 3, 4]
for index, val in enumerate(list):
     print index, val

For loop in a file

# filename is the relative or full path to the file
for line in open(filename):
    print line

Dictionary or hash

dict = {'Name': 'Moh', 'Age': 30, 'Phone': '4082163333'}
for key in dict:
        print key

for key, val in dict.items():
        print (key, val)

For loop through alphabets

import string
for i in string.ascii_lowercase:
    print i

For loop in a directory

import os
# dir_path is relative or full path to directory
for subdir, dirs, files in os.walk(dir_path):
    for file in files:
        print os.path.join(subdir, file)

Array 2D

array = [['00', '01', '02'], ['10', '11', '12'], ['20', '21', '22']]
for x in range(len(array)):
    for y in range(len(array[x])):
            print(array[x][y])

What is a for loop

Trying to explain a self explanatory concept may add to the confusion or complicate things that are assumed to be naturally simple. That is true but sometimes we take things for granted and the result is lack of solid understanding. Anyway, I will only provide the basic description here and provide pointers to some related advanced topics at the end.

python_for_loop

A loop is a control structure that allows a program to repeat a block of code multiple times until a certain condition is met. Why is this important despite its simplicity ? Well, counting, calculating averages, searching for items, computing a mathematical function using numerical analysis, etc are all direct applications of repetition or iteration for better terminology.

Loop Syntax

Regardless of programming language, loops have a similar structure but they may slightly differ in syntax. For example, C/C++ implements a count controlled loop which looks like:

for (i=0; i < n; i++)
{
   # code block
}

The code block above executes (n) times and the loop exits whenever n >= n. Python does not implement this kind of loop. Python implements an iterator based for loop that iterates over an enumeration of a set of items. Here is how a for loop in Python looks like

for val in sequence:
    block of code

Please note that:

  • No brackets are needed, Python uses indentation to identify the body of the loop
  • sequence is any iterate-able object (List, Tuple, Dictionary, string, or a user defined object)
  • Block of code can be one or more statements or even another for loop (nested loop)
  • val is the variable that takes the value of the item inside the sequence on each iteration

Python for loop Examples

To demonstrate the use of loops, take a look at the code snippets below. Each snippet implements a for loop to solve a particular problem.

Computing Stats

The following loop computes basic stats for an array of positive integers

array = [1, 3, 5, 7, 9]

max = array[0]
min = array[0]
count = 0
sum = 0

for num in array:
    count = count + 1
    sum = sum + num
    if num > max:
        max = num
    if num < min:
        min = num

print "Max = %d" %max
print "Min = %d" %min
print "Count = %d" %count
print "Sum = %d" %sum

Item Lookup

The following loop searches for number 7 in an array of positive integers

array = [1, 3, 5, 7, 9]
found = "not found"
item = 7
for num in array:
    if num == item:
        found = "found"
print "Item is %s" %found

Power Function

The following loop computes 3 raised to the power of 4 which is 81

x = 3
n = 4

R = x
k = 1

for k in range(n-1):
	R = R * x
	k = k + 1

print R

Factorial Function

The following loop computes the factorial of 4 which is 24

n = 4

R = 1  
k = 1  
    
for k in range(n): 
    k = k + 1
    R = R * k

print R

Prime Numbers

The following loop checks if a number is prime (you may check this article as well):

n = 15
p = 1

for d in range(2, n):
	if n % d == 0:
		p = 0
		break
if p == 1:
	print "%d is prime number" %n
else:
	print "%d is not a prime number" %n

Newton’s Method for Square Root

Iteration is used in numerical analysis to compute approximations of mathematical functions. For example, one of the fastest ways to compute a square root is Newton's method. Start with any value (v) then compute a better approximation of sqrt(n) using the following formula

sqrt(n) = (v + n/v)/2

Let us implement that using a Python for loop

# Compute square root of 8
n = 8

# Iterations number
t = 10

# Initial approximation
v = 1.0

for i in range(t):
	# Compute approximation 
	s = (v + n/v)/2.0
	# Use computed approximation as new value
	v = s
	
print "Square root is %f" %s

Python Infinite Loops

The body of a loop can run endlessly if the exit condition is not met. This behavior can be unintentional or on purpose. Unintentional infinite loops are nasty bugs that must be fixed immediately. On the other hand, infinite loops can be used for good reasons. For example, in a 3D game, a loop runs forever during game play until the user quits the game. Infinite loops in Python are more likely to happen using the while loop as opposed to the for loop. Python for loops have no explicit exit condition so the loop exits normally in most cases. Unless the programmer is using his own buggy implementation of an iterateable sequence, in that case the for loop can run for ever.

Python Nested Loops

Loops can be nested inside each other so that an inner loop represents the body of its containing outer loop. When working with nested loops one has to be aware of the tradeoff between convenience and performance. For example, the code to process a two dimensional array using a doubly nested for loop is easier to read but it might not be the fastest way to do that. You can store a two dimensional array in one dimensional array and calculate item indexes instead of using a second loop (You can check out this article). One way to help you understand how nested loops work is to look at the following examples

1 loop to process a list of items

list = [1, 2, 3, 4, 5]
for item in list:
   print item

2 loops to process a table of items

row1 = ["row1:column1", "row1:column2"]
row2 = ["row2:column1", "row2:column2"]
table = [row1, row2]

for row in range(2):
   for col in range(2):
      print table[row][col]

Break statement

Python like other languages provides a special purpose statement called break. This statement terminates the loop immediately and control is returned to the statement right after the body of the loop. As we mentioned earlier, an infinite loop can be used on purpose as in computer games. To quit the game, a break statement is used to terminate the infinite game loop. Another example, imagine you are searching for an element in a long array. If you find that element near the beginning of the list, there is no point to continue the search to the end of the list.

Here is an example

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
item = 7
for num in numbers:
    print num
    if num == item:
        break

If you execute the code above, you will notice that all numbers are printed except 8 and 9 because the loop was terminated when we found 7

Continue statement

This statement is used to skip the remaining code in the body of the loop and continue iteration. You can always use if statements to implement the same logic but using continue is nice for code clarity and readability. Here is an example

numbers = [1, 2, 3, 4, 5, 6]
for num in numbers:
	if num % 2 == 0:
		continue
	print num

If you execute the code above it will only print the odd numbers 1, 3, 5

Python loop Else Statement

The else clause when used in a loop runs only when the loop exits normally (without using a break). Again, this is a nice feature that makes your code more readable however you can always write an equivalent code of your own. Take a look at the following code snippets:

Not using an else clause to check if 3 exists in the list

numbers = [1, 2, 3, 4, 5, 6]
found = False
for num in numbers:
	if num == 3:
		found = True
		break	
if found:
	print "List contains 3"
else:
	print "List does not contain 3"

Using an else clause to check if 3 exists in the list

numbers = [1, 2, 4, 5, 6]
for num in numbers:
	if num == 3:
		print "List contains 3"
		break
else:
	print "List does not contain 3"

As you can see, it is essentially the same logic. The only difference is utilizing a code feature that makes your code cleaner and easy to read. The use of the else clause saved us from using an extra flag variable (found boolean variable)

Python Pass Statement

This is like a no operation statement or do nothing. As before, this language feature is a convenience and can always be replaced with an equivalent code of ours. It is useful when the code goes into an unimplemented functionality (ex. stubs). Here is an example:

numbers = [1, 2, 3, 4, 5, 6]
for num in numbers:
	if num % 2 == 0:
		pass
		print "Processing number : %d" %num
	else:
		continue


In the code above, we are detecting even numbers and want to process them however the code to process them is not implemented yet.

Advanced Loops and Tricks

In the following sections, we are going to briefly touch on a bit more advanced topics related to loops. The goal is better understanding not completeness. Fore more details about each topic, will leave that to the reader.

Iteration vs Recursion

Whenever loops are mentioned, the classical debate of iteration vs recursion pops up. Any problem that can be solved in one technique can be solved with the other. It all depends on code readability, maintenance and performance. Generally speaking, an iterative approach can be faster than a recursive one as recursion involves function calls, overhead and pushing state to the stack memory. In some cases, a recursive approach is not only more elegant but also much faster. Take a look at the following examples:

  • Refer to the following article for an iterative approach to print Fibonacci Numbers
  • Refer to the following article for a recursive approach to computing the greatest common divisor (GCD)

Loop Invariants

Loop invariant is one of the interesting topics related to loops. I highly recommend any one in the computer science field to get familiar with this topic. It helps in making sense of the solutions (for the known problems) that we are all familiar with. Sometimes, we spend quite a lot of time trying to initialize a loop to solve a certain problem and fail miserably. Loop invariants help you do that without pulling your hair off. I wrote a series of posts on the topic which you can find here. I hope you enjoy it.

Iterators

In Python, in order to implement an iterator object, it has to conform to the iterator protocol. This means that the object has to implement the __iter__() and next() methods. The first is implicitly called at the start of the loops. The second returns the next value in sequence and called on each iteration. The following example iterator object list odd numbers in a range of integers.

class OddNumbersInRange:
    def __init__(self, a, b):
    
    	# Initialize range of numbers
        self.begin = a
        self.end = b   
        
        # Curent odd number could be the first number
        # If not then it is the next one
        self.current = a     
        if a % 2 == 0:
        	self.current = a + 1

    def __iter__(self):
        return self

	# Get next odd number
    def next(self):
    	# Stop if reach end of range
    	if self.current > self.end:
            raise StopIteration
        else:
        	# Next odd number
    		self.current += 2
        	return self.current - 2 

# Print all odd number between 1 and 9
for odd in OddNumbersInRange(1, 9):
    print odd

List Comprehensions

List comprehension (LC for short) in Python is an elegant way to create a list. It is a powerful and cool language feature. It makes your code clean, readable and in some cases may improve performance. If you fall in love with list comprehensions, I am afraid you are not going to pay attention to for loops anymore. Please do not do that as I have put a lot of time creating this post all about loops. LC is the preferred choice of mathematicians to define sets. Let us look at some examples:

Odd numbers between 0 and 10 using a for loop

for x in range(10):
	if x%2 == 1:
		print x

Using a list comprehension:

	
odd = [x for x in range(10) if x%2 == 1]
for x in odd:
	print x 

Flattening a two dimensional array using a nested loop

array = [['00', '01', '02'], ['10', '11', '12'], ['20', '21', '22']]  
             
f = []
for x in range(len(array)):  
    for y in range(len(array[x])):  
            f.append(array[x][y])
print f

using a list comprehension

array = [['00', '01', '02'], ['10', '11', '12'], ['20', '21', '22']]
print [array[x][y] for x in range(len(array)) for y in range(len(array[x]))]

The output should look like:

['00', '01', '02', '10', '11', '12', '20', '21', '22']

As you can see, list comprehensions syntax is quite simple:

[output_expression for variable in input_sequence if filter_condition]

We can go fancy with list comprehensions but let us stop and move on to the next section.

Zip Function

The Zip function in Python is used to iterate over multiple sequences simultaneously. It takes one element from the first list and combines it with the corresponding element in the second list. It saves us from using for loops with performance gain. Assume we have two separate lists for keys and values. We want to create a dictionary out of these lists. One way to do that is to use a for loop:

keys = ['name', 'age']
vals = ['Mark', 30]
d = {}
for i, key in enumerate(keys):
	d[key] = vals[i]
print d

but we can use the zip function as follows:

keys = ['name', 'age']
vals = ['Mark', 30]
d = dict(zip(keys, vals))
print d

There are many situations where the zip function can help in writing fast, compact and easy to read code. For example, the zip function is very useful in matrix operations such as matrix transpose. Let us stop here. This was just a brief description of the zip function as it relates to loops. For more information, I recommend that you research zip, map and lambda functions separately. Before I end, I would like to share some tools and references:

Python Tools

You can use the following online tools to try your code online without the need to install anything. You just need a web browser.

References

That is all. I hope you enjoyed the post. Please leave comments below if you have questions or remarks.

One Comment

Leave a Reply