note.nkmk.me

for loop in Python (with range, enumerate, zip, etc.)

Posted: 2020-08-24 / Tags: Python

Explain the for loop in Python.

  • Basics of the for loop in Python
    • for statement in Python
    • Terminate the for loop: break
    • Continue to the next cycle: continue
    • Execute after normal termination: else
  • Functions that are useful in for statements
    • Extract only some elements: slice
    • Counter (index): range()
    • Elements and counter: enumerate()
    • Multiple lists: zip()
    • Multiple lists and counter: enumerate(), zip()
    • Reverse order: reversed()
    • Nested loop: itertools.product()
  • Other topics
    • dict in for statement
    • List comprehensions
Sponsored Link

for statement in Python

A for statement (for-loop) in many programming languages like C is written using a counter (index) variable and a continuation condition.

for(int i = 0; i < 10; i++)
    ...

Unlike C, the for statement in Python is written as follows. You can set any name to variable

for variable in iterable object:
    ...

Corresponding to a foreach statement in other languages, elements of iterable objects such as lists are sequentially assigned to variables and processed. The process is repeated for all elements.

l = ['Alice', 'Bob', 'Charlie']

for name in l:
    print(name)
# Alice
# Bob
# Charlie
source: for_usage.py

Terminate the for loop: break

You can terminate the for loop by break.

l = ['Alice', 'Bob', 'Charlie']

for name in l:
    if name == 'Bob':
        print('!!BREAK!!')
        break
    print(name)
# Alice
# !!BREAK!!
source: for_usage.py

See the following post for details on the if statement.

Continue to the next cycle: continue

You can skip the cycle and continue to the next by continue.

break terminates the entire for loop, but continue only skips the code after the continue statement in the cycle.

l = ['Alice', 'Bob', 'Charlie']

for name in l:
    if name == 'Bob':
        print('!!SKIP!!')
        continue
    print(name)
# Alice
# !!SKIP!!
# Charlie
source: for_usage.py

Execute after normal termination: else

Use else if you want to execute something after the for loop has completed successfully.

l = ['Alice', 'Bob', 'Charlie']

for name in l:
    print(name)
else:
    print('!!FINISH!!')
# Alice
# Bob
# Charlie
# !!FINISH!!
source: for_usage.py

If the for loop is terminated by break, the suite in the else clause is not executed.

for name in l:
    if name == 'Bob':
        print('!!BREAK!!')
        break
    print(name)
else:
    print('!!FINISH!!')
# Alice
# !!BREAK!!
source: for_usage.py

In the case of continue, the suite in the else clause is executed.

for name in l:
    if name == 'Bob':
        print('!!SKIP!!')
        continue
    print(name)
else:
    print('!!FINISH!!')
# Alice
# !!SKIP!!
# Charlie
# !!FINISH!!
source: for_usage.py

By using else and continue, you can break out of nested loops (multiple loops). See the following post for details.

Extract only some elements: slice

If you want to extract only some elements, specify the range with a slice like [start:stop]. For start and stop, specify the index starting with 0. Note that the element at the position of stop is not included.

l = ['A', 'B', 'C', 'D', 'E', 'F', 'G']

for c in l[2:5]:
    print(c)
# C
# D
# E
source: for_usage.py

You can omit start and stop, or get the element for each step with [start:stop:step]. An example of extracting only odd-indexed elements and even-indexed elements is as follows.

for c in l[::2]:
    print(c)
# A
# C
# E
# G

for c in l[1::2]:
    print(c)
# B
# D
# F
source: for_usage.py

See the following post for more information about slice.

Counter (index): range()

You can get the counter (index) in the for loop by range().

for i in range(3):
    print(i)
# 0
# 1
# 2
source: for_range.py

range() returns an object of type range.

print(range(3))
print(type(range(3)))
# range(0, 3)
# <class 'range'>
source: for_range.py

For explanation, convert it to a list with list(). You don't need to convert it to a list when using it in a for statement like the above example.

range(stop) returns numbers of 0 <= i <stop.

print(list(range(3)))
# [0, 1, 2]

print(list(range(6)))
# [0, 1, 2, 3, 4, 5]
source: for_range.py

If you want to specify a range, specify two arguments like range(start, stop).

print(list(range(10, 13)))
# [10, 11, 12]
source: for_range.py

If you want to specify arbitrary increments, specify three arguments like range(start, stop, step).

print(list(range(0, 10, 3)))
# [0, 3, 6, 9]

print(list(range(10, 0, -3)))
# [10, 7, 4, 1]
source: for_range.py

An example of the for statement is as follows.

for i in range(10, 0, -3):
    print(i)
# 10
# 7
# 4
# 1
source: for_range.py

See the following article for details of range().

Elements and counter: enumerate()

You can get the element and counter (index) at the same time by enumerate().

l = ['Alice', 'Bob', 'Charlie']

for name in l:
    print(name)
# Alice
# Bob
# Charlie

for i, name in enumerate(l):
    print(i, name)
# 0 Alice
# 1 Bob
# 2 Charlie

A start value can be specified as the second argument of enumerate().

for i, name in enumerate(l, 1):
    print(i, name)
# 1 Alice
# 2 Bob
# 3 Charlie

for i, name in enumerate(l, 42):
    print(i, name)
# 42 Alice
# 43 Bob
# 44 Charlie

enumerate() has no argument to specify step like range(), but it can be done as follows.

step = 3
for i, name in enumerate(l):
    print(i * step, name)
# 0 Alice
# 3 Bob
# 6 Charlie
Sponsored Link

Multiple lists: zip()

Multiple iterable objects can be handled by zip().

names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]

for name, age in zip(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18

It is also possible to combine three or more iterable objects.

points = [100, 85, 90]

for name, age, point in zip(names, ages, points):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 90

See the following post for details such as when the number of elements is different.

As in the example above, zip() returns the elements of multiple iterable objects in order. If you want to get all combinations of elements of multiple iterable objects, use itertools.product() described later.

Multiple lists and counter: enumerate(), zip()

You can use enumerate() and zip() at the same time. Note that whole variable names for zip() must be enclosed in parentheses ().

names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]

for i, (name, age) in enumerate(zip(names, ages)):
    print(i, name, age)
# 0 Alice 24
# 1 Bob 50
# 2 Charlie 18

Reverse order: reversed()

You can get the elements of an iterable object in reverse order by reversed()

l = ['Alice', 'Bob', 'Charlie']

for name in reversed(l):
    print(name)
# Charlie
# Bob
# Alice

The range object can also be reversed. You can specify a negative value for step without using reversed().

for i in reversed(range(3)):
    print(i)
# 2
# 1
# 0

for i in range(2, -1, -1):
    print(i)
# 2
# 1
# 0

The enumerate object cannot be reversed. You need to convert it to a list with list().

# for i, name in reversed(enumerate(l)):
#     print(i, name)
# TypeError: 'enumerate' object is not reversible

for i, name in reversed(list(enumerate(l))):
    print(i, name)
# 2 Charlie
# 1 Bob
# 0 Alice

If you don't want to reverse the index, use reversed() within enumerate().

for i, name in enumerate(reversed(l)):
    print(i, name)
# 0 Charlie
# 1 Bob
# 2 Alice

The zip object cannot be reversed. You need to convert it to a list with list().

l2 = [24, 50, 18]

# for name, age in reversed(zip(l, l2)):
#     print(name, age)
# TypeError: 'zip' object is not reversible

for name, age in reversed(list(zip(l, l2))):
    print(name, age)
# Charlie 18
# Bob 50
# Alice 24

Nested loop: itertools.product()

You can write a nested loop in Python as follows. In Python, blocks are represented by indents, so just add more indents.

l1 = [1, 2, 3]
l2 = [10, 20, 30]

for i in l1:
    for j in l2:
        print(i, j)
# 1 10
# 1 20
# 1 30
# 2 10
# 2 20
# 2 30
# 3 10
# 3 20
# 3 30

You can get the same result by itertools.product().

import itertools

l1 = [1, 2, 3]
l2 = [10, 20, 30]

for i, j in itertools.product(l1, l2):
    print(i, j)
# 1 10
# 1 20
# 1 30
# 2 10
# 2 20
# 2 30
# 3 10
# 3 20
# 3 30

dict in for statement

The dict object in the for statement returns keys.

d = {'key1': 1, 'key2': 2, 'key3': 3}

for k in d:
    print(k)
# key1
# key2
# key3

If you want to get values or key-value pairs, use values() and items().

for v in d.values():
    print(v)
# 1
# 2
# 3
for k, v in d.items():
    print(k, v)
# key1 1
# key2 2
# key3 3

See the following post for details.

List comprehensions

To generate a new list by processing the elements of iterable objects, it is simpler to write using list comprehensions than the for statement.

List comprehension is written as follows.

[expression for variable_name in iterable]

Examples of list comprehensions and for statement is as follows. List comprehensions are more concise.

squares = [i**2 for i in range(5)]
print(squares)
# [0, 1, 4, 9, 16]
squares = []
for i in range(5):
    squares.append(i**2)

print(squares)
# [0, 1, 4, 9, 16]

See the following post for details on list comprehensions.

Sponsored Link
Share

Related Categories

Related Posts