12. Loops

Iteration with while loops

Another powerful feature of programming languages, closely related to branching, is running one or more statements multiple times. This feature is often referred to as iteration on looping, and there are two ways to do this in Python: using while loops and for loops.

while loops have the following syntax:

while condition:
    statement(s)

Statements in the code block under while are executed repeatedly as long as the condition evaluates to True. Generally, one of the statements under while makes some change to a variable that causes the condition to evaluate to False after a certain number of iterations.

Let's try to calculate the factorial of 100 using a while loop. The factorial of a number n is the product (multiplication) of all the numbers from 1 to n, i.e., 1*2*3*...*(n-2)*(n-1)*n.

In [38]:

result = 1
i = 1

while i <= 100:
    result = result * i
    i = i+1

print(f'The factorial of 100 is: {result}')
The factorial of 100 is: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

Here's how the above code works:

  • We initialize two variables, result and, i. result will contain the final outcome. And i is used to keep track of the next number to be multiplied with result. Both are initialized to 1 (can you explain why?)

  • The condition i <= 100 holds true (since i is initially 1), so the while block is executed.

  • The result is updated to result * i, i is increased by 1 and it now has the value 2.

  • At this point, the condition i <= 100 is evaluated again. Since it continues to hold true, result is again updated to result * i, and i is increased to 3.

  • This process is repeated till the condition becomes false, which happens when i holds the value 101. Once the condition evaluates to False, the execution of the loop ends, and the print statement below it is executed.

Can you see why result contains the value of the factorial of 100 at the end? If not, try adding print statements inside the while block to print result and i in each iteration.

Iteration is a powerful technique because it gives computers a massive advantage over human beings in performing thousands or even millions of repetitive operations really fast. With just 4-5 lines of code, we were able to multiply 100 numbers almost instantly. The same code can be used to multiply a thousand numbers (just change the condition to i <= 1000) in a few seconds.

You can check how long a cell takes to execute by adding the magic command %%time at the top of a cell. Try checking how long it takes to compute the factorial of 100, 1000, 10000, 100000, etc.

Here's another example that uses two while loops to create an interesting pattern.

Infinite Loops

Suppose the condition in a while loop always holds true. In that case, Python repeatedly executes the code within the loop forever, and the execution of the code never completes. This situation is called an infinite loop. It generally indicates that you've made a mistake in your code. For example, you may have provided the wrong condition or forgotten to update a variable within the loop, eventually falsifying the condition.

If your code is stuck in an infinite loop during execution, just press the "Stop" button on the toolbar (next to "Run") or select "Kernel > Interrupt" from the menu bar. This will interrupt the execution of the code. The following two cells both lead to infinite loops and need to be interrupted.

# INFINITE LOOP - INTERRUPT THIS CELL

result = 1
i = 1

while i <= 100:
    result = result * i
    # forgot to increment i
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-41-5234d8c241fc> in <module>
      5 
      6 while i <= 100:
----> 7     result = result * i
      8     # forgot to increment i

KeyboardInterrupt: 

In [42]:

# INFINITE LOOP - INTERRUPT THIS CELL

result = 1
i = 1

while i > 0 : # wrong condition
    result *= i
    i += 1
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-42-c4abf72fce4d> in <module>
      5 
      6 while i > 0 : # wrong condition
----> 7     result *= i
      8     i += 1

KeyboardInterrupt: 

break and continue statements

You can use the break statement within the loop's body to immediately stop the execution and break out of the loop (even if the condition provided to while still holds true).

In [43]:

i = 1
result = 1

while i <= 100:
    result *= i
    if i == 42:
        print('Magic number 42 reached! Stopping execution..')
        break
    i += 1
    
print('i:', i)
print('result:', result)
Magic number 42 reached! Stopping execution..
i: 42
result: 1405006117752879898543142606244511569936384000000000

As you can see above, the value of i at the end of execution is 42. This example also shows how you can use an if statement within a while loop.

Sometimes you may not want to end the loop entirely, but simply skip the remaining statements in the loop and continue to the next loop. You can do this using the continue statement.

i = 1
result = 1

while i < 20:
    i += 1
    if i % 2 == 0:
        print(f'Skipping {i}')
        continue
    print(f'Multiplying with {i}')
    result = result * i
    
print('i:', i)
print('result:', result)
Skipping 2
Multiplying with 3
Skipping 4
Multiplying with 5
Skipping 6
Multiplying with 7
Skipping 8
Multiplying with 9
Skipping 10
Multiplying with 11
Skipping 12
Multiplying with 13
Skipping 14
Multiplying with 15
Skipping 16
Multiplying with 17
Skipping 18
Multiplying with 19
Skipping 20
i: 20
result: 654729075

In the example above, the statement result = result * i inside the loop is skipped when i is even, as indicated by the messages printed during execution.

Logging: The process of adding print statements at different points in the code (often within loops and conditional statements) for inspecting the values of variables at various stages of execution is called logging. As our programs get larger, they naturally become prone to human errors. Logging can help in verifying the program is working as expected. In many cases, print statements are added while writing & testing some code and are removed later.

Iteration with for loops

A for loop is used for iterating or looping over sequences, i.e., lists, tuples, dictionaries, strings, and ranges. For loops have the following syntax:

for value in sequence:
    statement(s)

The statements within the loop are executed once for each element in sequence. Here's an example that prints all the element of a list.

In [46]:

days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']

for day in days:
    print(day)
Monday
Tuesday
Wednesday
Thursday
Friday

Let's try using for loops with some other data types.

# Looping over a string
for char in 'Monday':
    print(char)
M
o
n
d
a
y

In [48]:

# Looping over a tuple
for fruit in ['Apple', 'Banana', 'Guava']:
    print("Here's a fruit:", fruit)
Here's a fruit: Apple
Here's a fruit: Banana
Here's a fruit: Guava

In [49]:

# Looping over a dictionary
person = {
    'name': 'John Doe',
    'sex': 'Male',
    'age': 32,
    'married': True
}

for key in person:
    print("Key:", key, ",", "Value:", person[key])
Key: name , Value: John Doe
Key: sex , Value: Male
Key: age , Value: 32
Key: married , Value: True

Note that while using a dictionary with a for loop, the iteration happens over the dictionary's keys. The key can be used within the loop to access the value. You can also iterate directly over the values using the .values method or over key-value pairs using the .items method.

In [50]:

for value in person.values():
    print(value)
John Doe
Male
32
True

In [51]:

for key_value_pair in person.items():
    print(key_value_pair)
('name', 'John Doe')
('sex', 'Male')
('age', 32)
('married', True)

Since a key-value pair is a tuple, we can also extract the key & value into separate variables.

for key, value in person.items():
    print("Key:", key, ",", "Value:", value)
Key: name , Value: John Doe
Key: sex , Value: Male
Key: age , Value: 32
Key: married , Value: True

Iterating using range and enumerate

The range function is used to create a sequence of numbers that can be iterated over using a for loop. It can be used in 3 ways:

  • range(n) - Creates a sequence of numbers from 0 to n-1

  • range(a, b) - Creates a sequence of numbers from a to b-1

  • range(a, b, step) - Creates a sequence of numbers from a to b-1 with increments of step

Let's try it out.

In [53]:

for i in range(7):
    print(i)
0
1
2
3
4
5
6

In [54]:

for i in range(3, 10):
    print(i)
3
4
5
6
7
8
9

In [55]:

for i in range(3, 14, 4):
    print(i)
3
7
11

break, continue and pass statements

Similar to while loops, for loops also support the break and continue statements. break is used for breaking out of the loop and continue is used for skipping ahead to the next iteration.

In [58]:

weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']

In [59]:

for day in weekdays:
    print('Today is {}'.format(day))
    if (day == 'Wednesday'):
        print("I don't work beyond Wednesday!")
        break
Today is Monday
Today is Tuesday
Today is Wednesday
I don't work beyond Wednesday!

In [60]:

for day in weekdays:
    if (day == 'Wednesday'):
        print("I don't work on Wednesday!")
        continue
    print('Today is {}'.format(day))
Today is Monday
Today is Tuesday
I don't work on Wednesday!
Today is Thursday
Today is Friday

Like if statements, for loops cannot be empty, so you can use a pass statement if you don't want to execute any statements inside the loop.

In [61]:

for day in weekdays:
    pass

Nested for and while loops

Similar to conditional statements, loops can be nested inside other loops. This is useful for looping lists of lists, dictionaries etc.

In [62]:

persons = [{'name': 'John', 'sex': 'Male'}, {'name': 'Jane', 'sex': 'Female'}]

for person in persons:
    for key in person:
        print(key, ":", person[key])
    print(" ")
name : John
sex : Male
 
name : Jane
sex : Female
days = ['Monday', 'Tuesday', 'Wednesday']
fruits = ['apple', 'banana', 'guava']

for day in days:
    for fruit in fruits:
        print(day, fruit)
Monday apple
Monday banana
Monday guava
Tuesday apple
Tuesday banana
Tuesday guava
Wednesday apple
Wednesday banana
Wednesday guava

With this, we conclude our discussion of branching and loops in Python.

Questions for Revision

Try answering the following questions to test your understanding of the topics covered in this notebook:

  1. What is iteration or looping in programming languages? Why is it useful?

  2. What are the two ways for performing iteration in Python?

  3. What is the purpose of the while statement in Python?

  4. What is the syntax of the white statement in Python? Give an example.

  5. Write a program to compute the sum of the numbers 1 to 100 using a while loop.

  6. Repeat the above program for numbers up to 1000, 10000, and 100000. How long does it take each loop to complete?

  7. What is an infinite loop?

  8. What causes a program to enter an infinite loop?

  9. How do you interrupt an infinite loop within Jupyter?

  10. What is the purpose of the break statement in Python?

  11. Give an example of using a break statement within a while loop.

  12. What is the purpose of the continue statement in Python?

  13. Give an example of using the continue statement within a while loop.

  14. What is logging? How is it useful?

  15. What is the purpose of the for statement in Python?

  16. What is the syntax of for loops? Give an example.

  17. How are for loops and while loops different?

  18. How do you loop over a string? Give an example.

  19. How do you loop over a list? Give an example.

  20. How do you loop over a tuple? Give an example.

  21. How do you loop over a dictionary? Give an example.

  22. What is the purpose of the range statement? Give an example.

  23. What is the purpose of the enumerate statement? Give an example.

  24. How are the break, continue, and pass statements used in for loops? Give examples.

  25. Can loops be nested within other loops? How is nesting useful?

  26. Give an example of a for loop nested within another for loop.

  27. Give an example of a while loop nested within another while loop.

  28. Give an example of a for loop nested within a while loop.

  29. Give an example of a while loop nested within a for loop.

Last updated