Python
foreach
Python loops
iteration
Python 3

Is there a 'foreach' function in Python 3?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Python does not have a foreach keyword or function. The for loop in Python IS the foreach — it iterates directly over elements of any iterable (lists, tuples, dicts, sets, strings, generators) without needing an index. Where languages like PHP use foreach ($items as $item) or JavaScript uses items.forEach(callback), Python uses for item in items. This design is intentional — Python prefers a single, clear way to iterate.

Python's for Loop IS foreach

python
1# Python — this IS foreach
2fruits = ['apple', 'banana', 'cherry']
3for fruit in fruits:
4    print(fruit)
5# apple
6# banana
7# cherry
8
9# PHP equivalent
10# foreach ($fruits as $fruit) { echo $fruit; }
11
12# JavaScript equivalent
13# fruits.forEach(fruit => console.log(fruit));
14
15# Java equivalent
16# for (String fruit : fruits) { System.out.println(fruit); }

Iterating Over Different Types

python
1# List
2for item in [1, 2, 3]:
3    print(item)
4
5# Tuple
6for item in (1, 2, 3):
7    print(item)
8
9# String (iterates characters)
10for char in "hello":
11    print(char)
12
13# Set
14for item in {1, 2, 3}:
15    print(item)
16
17# Dictionary (iterates keys by default)
18data = {'a': 1, 'b': 2, 'c': 3}
19for key in data:
20    print(key, data[key])
21
22# Dictionary values
23for value in data.values():
24    print(value)
25
26# Dictionary key-value pairs
27for key, value in data.items():
28    print(f"{key} = {value}")
29
30# Range
31for i in range(5):
32    print(i)  # 0, 1, 2, 3, 4

With Index (enumerate)

python
1fruits = ['apple', 'banana', 'cherry']
2
3# Need the index? Use enumerate
4for index, fruit in enumerate(fruits):
5    print(f"{index}: {fruit}")
6# 0: apple
7# 1: banana
8# 2: cherry
9
10# Start from a different index
11for index, fruit in enumerate(fruits, start=1):
12    print(f"{index}: {fruit}")
13# 1: apple
14# 2: banana
15# 3: cherry

Functional Alternatives

While Python prefers for loops, functional-style iteration exists:

python
1# map() — apply a function to each element
2numbers = [1, 2, 3, 4, 5]
3squares = list(map(lambda x: x ** 2, numbers))
4# [1, 4, 9, 16, 25]
5
6# filter() — keep elements matching a condition
7evens = list(filter(lambda x: x % 2 == 0, numbers))
8# [2, 4]
9
10# List comprehension — preferred over map/filter in Python
11squares = [x ** 2 for x in numbers]
12evens = [x for x in numbers if x % 2 == 0]

Simulating forEach with Side Effects

If you want to apply a function to each element (like JavaScript's forEach):

python
1# Using a for loop (Pythonic)
2items = ['a', 'b', 'c']
3for item in items:
4    process(item)
5
6# Using map with side effects (NOT recommended)
7# map() is lazy — must consume the iterator
8list(map(process, items))  # Works but unpythonic
9
10# Using a one-liner (not recommended for complex logic)
11[process(item) for item in items]  # Creates unnecessary list
12
13# The correct way — just use a for loop
14for item in items:
15    process(item)

Iterating in Parallel (zip)

python
1names = ['Alice', 'Bob', 'Charlie']
2ages = [30, 25, 35]
3
4# Iterate two lists together
5for name, age in zip(names, ages):
6    print(f"{name} is {age}")
7
8# With three lists
9scores = [95, 87, 92]
10for name, age, score in zip(names, ages, scores):
11    print(f"{name}, age {age}, scored {score}")
12
13# zip stops at shortest — use zip_longest for uneven lists
14from itertools import zip_longest
15for a, b in zip_longest([1, 2, 3], [10, 20], fillvalue=0):
16    print(a, b)  # (1,10), (2,20), (3,0)

Itertools for Advanced Iteration

python
1from itertools import chain, product, groupby
2
3# chain — iterate multiple iterables as one
4for item in chain([1, 2], [3, 4], [5]):
5    print(item)  # 1, 2, 3, 4, 5
6
7# product — nested loops as a single iterator
8for x, y in product(range(3), range(3)):
9    print(f"({x}, {y})")  # (0,0), (0,1), (0,2), (1,0), ...
10
11# groupby — group consecutive elements
12data = sorted([('A', 1), ('B', 2), ('A', 3)], key=lambda x: x[0])
13for key, group in groupby(data, key=lambda x: x[0]):
14    print(key, list(group))  # A [('A', 1), ('A', 3)], B [('B', 2)]

Why Python Doesn't Have foreach

Python follows the "there should be one obvious way to do it" philosophy. The for loop already handles every iteration use case:

  • for x in list — iterate elements
  • for i, x in enumerate(list) — iterate with index
  • for k, v in dict.items() — iterate key-value pairs
  • for a, b in zip(l1, l2) — iterate in parallel

Adding a separate foreach would be redundant.

Common Pitfalls

  • Modifying a list while iterating: for item in items: items.remove(item) skips elements because the list changes under the iterator. Iterate over a copy (for item in items[:]) or use list comprehension for filtering.
  • Using map() for side effects: map(print, items) is lazy — nothing prints until consumed. Use a for loop for side effects, not map() or list comprehension.
  • Forgetting that for over a dict iterates keys: for x in my_dict gives you keys, not values or key-value pairs. Use .values() or .items() for values or both.
  • Creating a list comprehension just for side effects: [send_email(u) for u in users] creates an unnecessary list of return values. Use a for loop instead.
  • Using range(len(list)) instead of enumerate: for i in range(len(items)): items[i] works but is less Pythonic and error-prone. Use for i, item in enumerate(items) instead.

Summary

  • Python's for item in iterable IS the foreach — no separate keyword or function exists
  • Use enumerate() when you need the index alongside the element
  • Use zip() to iterate multiple iterables in parallel
  • Prefer for loops over map() or list comprehensions for side effects
  • List comprehensions are the Pythonic alternative to map() and filter() for transformations

Course illustration
Course illustration

All Rights Reserved.