Looping statements are used to execute a piece of code repeatedly a specified number of times or until a given condition is met.  

The for loop is the most popular iterative control structure in Python. It makes it possible to iterate over a  collection of values, performing a certain task for each value. 

Syntax:
for <variable> in <sequence>: 
    <statements>
copy

The <variable> represents an identifier for the current  element in the <sequence>, within the loop body. The sequence can be any iterable object such as a list, a tuple, range, etc.  The <statements> are the set of instructions that the loop will execute each time it iterates through the sequence. The loop will continue until all elements of the sequence have been exhausted or until the break statement is encountered.

ExampleEdit & Run

use for loop to iterate a list

languages = ['Python', 'C++', 'Java', 'C#', 'PHP', 'Ruby']

for language in languages:
    print(language)
copy
Output:
Python C++ Java C# PHP Ruby [Finished in 0.010844357311725616s]

In the above example, the for loop iterates through the  list of languages printing each language after each iteration. The loop starts by setting the variable 'language' to the first item in the list ('Python'), and then prints the value of the language. It then moves on to the next item in the list ('C++'), prints the value, and so on until it has iterated through every item in the list.

For loops with range

Python includes the function range() which returns the integers in the specified range. In cases where we want to iterate over a range of integers, we can use the for loops with range  as the sequence.  

ExampleEdit & Run

use for loop to iterate through range values

for x in range(10): 
    print(x) 
copy
Output:
0 1 2 3 4 5 6 7 8 9 [Finished in 0.010183421894907951s]
ExampleEdit & Run
#loop over a range with 2 as the step
for i in range(0, 20, 2):
    print(i)
copy
Output:
0 2 4 6 8 10 12 14 16 18 [Finished in 0.01041515450924635s]

Iterating over  compound sequences

When we want to iterate over an object that is itself made of sequences, we can alias each element in the inner sequence using different variable names.

ExampleEdit & Run
cities = [('Tokyo', 'Japan'), ('Ottawa', 'Canada'), ('Helsinki', 'Finland'), ('Nairobi','Kenya')]

for city, country in cities:
    print(city, ',', country)
copy
Output:
Tokyo , Japan Ottawa , Canada Helsinki , Finland Nairobi , Kenya [Finished in 0.01042660977691412s]

Note that you can use as much as necessary element aliasing, the only condition is that the number of  names need  to match the number of elements in the inner sequence.

ExampleEdit & Run

 

product_list = [ ('Laptop', 800, 30), ('Monitor', 200, 10), ('Mouse', 30, 15), ('Keyboard', 50, 20), ('Speaker', 80, 5) ]

for item, price, quantity in product_list: 
      total_price = price * quantity 
      print('The total price for', item, 'is', total_price)
copy
Output:
The total price for Laptop is 24000 The total price for Monitor is 2000 The total price for Mouse is 450 The total price for Keyboard is 1000 The total price for Speaker is 400 [Finished in 0.010409889742732048s]

With dictionaries it is possible to alias the their keys and values separately using the items() method which returns a tuple of key-value pairs.. 

ExampleEdit & Run

looping over dictionary elements

D = {"a": 10, "b": 20, "c": 30} 

for key, value in D.items(): 
      print(f"{key} is mapped to {value}")
copy
Output:
a is mapped to 10 b is mapped to 20 c is mapped to 30 [Finished in 0.011285313405096531s]

The enumerate function

The buitin enumerate() function adds a counter to an iterable , we can use it with for loops in order to  keep the current index of the iteration. 

ExampleEdit & Run
L = ['Python', 'Django', 'Flask', 'Scipy', 'Numpy']

for index, value in enumerate(L):
   print(f'{index}: {value}')
copy
Output:
0: Python 1: Django 2: Flask 3: Scipy 4: Numpy [Finished in 0.011377744376659393s]

The break statement

The break statement is used when we want to pre-maturely  exit a loop. We can use it with for loops in order to exit the loop before the sequence elements are exhausted.

ExampleEdit & Run
for i in range(20):
   print(i)
   if i == 10:
      print('exited!')
      break
copy
Output:
0 1 2 3 4 5 6 7 8 9 10 exited! [Finished in 0.01077181100845337s]

The continue statement

The continue statement tells a loop to immediately start the next iteration. It skips all the remaining code inside the loop for the current iteration and proceeds directly to the next iteration. We can use this statement to skip some parts of a loop without breaking out of the loop.

ExampleEdit & Run
#The loop will move on to the next iteration when i == 5
for i in range(10):
   print(i)
   if i == 5:
      continue
copy
Output:
0 1 2 3 4 5 6 7 8 9 [Finished in 0.010330745950341225s]

The else statement

We can use for loops with the else statement. The else block will be executed if the loop terminates successfully without  encountering any break statement.  

ExampleEdit & Run

for loops with else

fruits = ["apple", "banana", "cherry"] 

for f in fruits: 
    print(f) 
else: 
    print("Finished!")
copy
Output:
apple banana cherry Finished! [Finished in 0.010548561811447144s]

In the following example the else block is not executed because the loop exits pre-maturely.

ExampleEdit & Run
nums = range(10) 

for i in nums: 
    print(i)
    if i == 5:
       break 
else: 
    print("Finished!")
copy
Output:
0 1 2 3 4 5 [Finished in 0.010611964389681816s]

Nested for loops

Nesting in loops is when a loop  is embedded within another loop. This makes it possible to perform more complex iterations over multiple data sets in a single loop statement.  

When a for loop appears inside of another for loop, the execution proceeds through the outer loop, then cycles through the inner loop. This process is repeated until all the outer loop iterations are complete.

ExampleEdit & Run

nested for loops

nums = [1, 2, 3]
letters = 'abc'

for i in nums:
    for l in letters:
        print(i, l)
copy
Output:
1 a 1 b 1 c 2 a 2 b 2 c 3 a 3 b 3 c [Finished in 0.010433847084641457s]

Nesting  makes it possible to cycle through multiple sequences simultaneously, making it easier to compare different sets of data or iterate through the same set multiple times.

ExampleEdit & Run
L1 = [1, 2]
L2 = [10, 20]
L3 = [100, 300]

for i in L1:
    for j in L2:
        for k in L3:
             print(i, j, k)
copy
Output:
1 10 100 1 10 300 1 20 100 1 20 300 2 10 100 2 10 300 2 20 100 2 20 300 [Finished in 0.010296759195625782s]

You can have as much nesting as necessary, however it is generally recommended to keep your nesting levels as less  as possible. A lot of nesting can easily make your program slow by a huge margin. It is also  difficult to read and manage when nesting goes too deep.