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
1 2 3 |
numbers = [1, 2, 3, 4, 5] for num in numbers: print "Current number is %d" % num |
For loop in a string
1 2 3 |
str = "Python is fun" for char in str: print "Current character is %c " % char |
For loop in a list of strings
1 2 3 |
planets = ['earth', 'mars', 'pluto'] for planet in planets: print "Current planet is %s" % planet |
For loop in a tuple
1 2 3 |
countries = ('USA', 'Italy', 'France') for country in countries: print "Current country is %s" % country |
For loop in a mixed list
1 2 3 |
Mixed = [1, 'Me', 2, 'You', 3, 'Them'] for item in Mixed: print "Current item is %r" % item |
For loop in a list of lists
1 2 3 4 |
lol = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]] for list in lol: for item in list: print item |
Range function
1 2 3 4 5 6 7 8 9 10 11 |
# 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)
1 2 3 |
# Numbers 0, -2, -4, -6 for i in range(0, -7, -2): print(i) |
Loop index
1 2 3 |
list = [1, 2, 3, 4] for index, val in enumerate(list): print index, val |
For loop in a file
1 2 3 |
# filename is the relative or full path to the file for line in open(filename): print line |
Dictionary or hash
1 2 3 4 5 6 |
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
1 2 3 |
import string for i in string.ascii_lowercase: print i |
For loop in a directory
1 2 3 4 5 |
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
1 2 3 4 |
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.
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:
1 2 3 4 |
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
1 2 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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
1 2 3 4 5 6 7 |
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
1 2 3 4 5 6 7 8 9 10 11 |
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
1 2 3 4 5 6 7 8 9 10 |
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):
1 2 3 4 5 6 7 8 9 10 11 |
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
1 |
sqrt(n) = (v + n/v)/2 |
Let us implement that using a Python for loop
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 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
1 2 3 |
list = [1, 2, 3, 4, 5] for item in list: print item |
2 loops to process a table of items
1 2 3 4 5 6 7 |
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
1 2 3 4 5 6 |
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
1 2 3 4 5 |
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
1 2 3 4 5 6 7 8 9 10 |
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
1 2 3 4 5 6 7 |
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:
1 2 3 4 5 6 7 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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
1 2 3 |
for x in range(10): if x%2 == 1: print x |
Using a list comprehension:
1 2 3 |
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
1 2 3 4 5 6 7 |
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
1 2 |
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:
1 |
['00', '01', '02', '10', '11', '12', '20', '21', '22'] |
As you can see, list comprehensions syntax is quite simple:
1 |
[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:
1 2 3 4 5 6 |
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:
1 2 3 4 |
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
- Code Academy
- Tutorials Point
- Google Developer
- Python.org Docs
- learn Python The Hard Way
- Learn Python
That is all. I hope you enjoyed the post. Please leave comments below if you have questions or remarks.
Thank you, Mohammad. As usual, the article is thorough and simple “plain-English” to understand and follow. Very useful!