Python Core Functions Zip & Enumerate Tutorial
Essential Tools Iteration Mastery

Python zip() & enumerate(): Complete Guide

Master Python's powerful iteration functions: zip() to combine multiple iterables, and enumerate() to add automatic counters. Write cleaner, more efficient Python code.

Combine Iterables

zip() function

Add Counters

enumerate() function

Step-by-step examples

With sample output

Real Applications

Data processing

Built-in iteration helpers

Python provides built-in functions:

  • zip() → combine iterables
  • enumerate() → add index while iterating

These functions make loops cleaner and easier.

Python zip() Function

What is zip()?

zip() combines multiple iterables element-by-element.

Syntax

zip(iterable1, iterable2, ...)

Basic Example

Basic Example
names = ["Rahul", "Ravi", "Kiran"]
marks = [90, 85, 95]

result = zip(names, marks)

print(list(result))

Output:

[('Rahul', 90), ('Ravi', 85), ('Kiran', 95)]

Using zip() with for Loop

zip() with for loop
names = ["A", "B", "C"]
scores = [70, 80, 90]

for name, score in zip(names, scores):
    print(name, score)

Output:

A 70
B 80
C 90

Creating dictionaries with zip()

A very common pattern is pairing two parallel lists into a dictionary using dict(zip(keys_or_names, values)).

dict(zip()) — score card
students = ["Rahul", "Ravi", "Kiran"]
scores = [90, 85, 95]

score_card = dict(zip(students, scores))
print(score_card)

Output:

{'Rahul': 90, 'Ravi': 85, 'Kiran': 95}

zip() with Different Length Lists

zip() stops at the shortest iterable.

Different lengths
a = [1, 2, 3]
b = ['x', 'y']

print(list(zip(a, b)))

Output:

[(1, 'x'), (2, 'y')]
zip() with strict=True (Python 3.10+)

By default, zip() stops when the shortest iterable ends—extra items in longer lists are silently dropped. That can hide data bugs. Pass strict=True to raise ValueError when lengths differ. Use this for validation and safer pipelines.

strict=True catches length mismatch
names = ["Rahul", "Ravi"]
marks = [90, 85, 95]

# Raises: ValueError: zip() argument 2 is longer than argument 1
list(zip(names, marks, strict=True))

Uncomment or run in a REPL to see the error; this is ideal when aligned rows must match exactly.

zip() with Multiple Iterables

Three iterables
names = ["Rahul", "Ravi"]
marks = [90, 85]
grades = ["A", "B"]

for data in zip(names, marks, grades):
    print(data)

Output:

('Rahul', 90, 'A')
('Ravi', 85, 'B')

Unzipping Using *

Unzip with *
data = [('A', 1), ('B', 2)]

names, numbers = zip(*data)

print(names)
print(numbers)

Output:

('A', 'B')
(1, 2)

Matrix transposition with zip(*matrix)

Unpacking rows into zip() is the usual one-liner to transpose a matrix (swap rows and columns).

Transpose a matrix
matrix = [[1, 2, 3],
          [4, 5, 6]]

transposed = list(zip(*matrix))
print(transposed)

Output:

[(1, 4), (2, 5), (3, 6)]

Converting zip Object

Convert to tuple
x = [1, 2]
y = [3, 4]

z = zip(x, y)

print(tuple(z))

Output:

((1, 3), (2, 4))

Applications of zip()

  • Combining student names and marks
  • Pairing keys and values
  • Matrix operations
  • Parallel iteration

Python enumerate() Function

What is enumerate()?

enumerate() adds an index to iterable elements.

Syntax

enumerate(iterable, start=0)

Basic Example

Basic Example
names = ["Rahul", "Ravi", "Kiran"]

for index, value in enumerate(names):
    print(index, value)

Output:

0 Rahul
1 Ravi
2 Kiran

Using Custom Start Index

start=1
names = ["A", "B", "C"]

for index, value in enumerate(names, start=1):
    print(index, value)

Output:

1 A
2 B
3 C

enumerate() with List

List of pairs
data = [10, 20, 30]

print(list(enumerate(data)))

Output:

[(0, 10), (1, 20), (2, 30)]

enumerate() on strings and lines

enumerate() works with any iterable—not only lists. Characters in a string and lines from a file (or a list stand-in) are common cases.

String — index each character
for i, char in enumerate("hello"):
    print(f"Index {i}: '{char}'")

Output:

Index 0: 'h'
Index 1: 'e'
Index 2: 'l'
Index 3: 'l'
Index 4: 'o'
Lines — simulated file content
lines = ["Line 1", "Line 2", "Line 3"]
for line_num, content in enumerate(lines, start=1):
    print(f"Line {line_num}: {content}")

Output:

Line 1: Line 1
Line 2: Line 2
Line 3: Line 3

With a real file, use for i, line in enumerate(open("file.txt"), start=1): (and prefer context managers for production code).

enumerate() vs Normal Loop

Without enumerate()

Manual counter
names = ["A", "B", "C"]

index = 0

for name in names:
    print(index, name)
    index += 1

With enumerate()

Using enumerate()
names = ["A", "B", "C"]

for index, name in enumerate(names):
    print(index, name)

enumerate() is cleaner and easier.

Combining zip() and enumerate()

Combined example
names = ["Rahul", "Ravi"]
marks = [90, 85]

for index, (name, mark) in enumerate(zip(names, marks), start=1):
    print(index, name, mark)

Output:

1 Rahul 90
2 Ravi 85

Time and space complexity

zip()
  • Time: O(n) where n is the length of the shortest input (each step advances all iterators once).
  • Space: The object itself is lazy—it does not build a full list until you call list() or similar.
enumerate()
  • Time: O(n) over the iterable length.
  • Space: Memory-efficient iterator—one (index, value) pair at a time.

zip() vs enumerate()

zip() enumerate()
Combines iterables Adds index
Used for parallel iteration Used for indexed iteration

Real-Life Examples

Function Example
zip() Student names with marks
enumerate() Ranking system

Advantages

zip()
  • Easy parallel looping
  • Cleaner code
  • Combines multiple lists
enumerate()
  • Automatic indexing
  • Cleaner loops
  • Reduces manual counters

Common pitfalls

  • zip() is a single-use iterator. After one full pass, it is exhausted. Calling list() twice on the same zip object gives an empty second result unless you recreate zip(...).
    Iterator exhausted after one use
    zipped = zip([1, 2], ['a', 'b'])
    print(list(zipped))   # [(1, 'a'), (2, 'b')]
    print(list(zipped))   # []
  • enumerate() starts at 0 unless you pass start=—easy to forget when you want human-readable numbering.
  • Do not modify a list while iterating it with enumerate(): elements can be skipped or indexes invalidated. Loop over a copy (e.g. for i, x in enumerate(items[:]):) if removal is required.

Challenge yourself

Given names = ["Alice", "Bob", "Charlie"] and scores = [85, 92, 78], use enumerate() and zip() together so the output is:

1. Alice scored 85
2. Bob scored 92
3. Charlie scored 78
Show solution
Solution
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]

for i, (name, score) in enumerate(zip(names, scores), start=1):
    print(f"{i}. {name} scored {score}")

Try it yourself

Edit the snippet below, then copy it into the Python REPL, VS Code, or an online interpreter (Python runs on your machine or server—not in the browser).

Quick recap

  • zip() pairs sequences; it stops at the shortest iterable—use strict=True (3.10+) to fail on length mismatch.
  • dict(zip(keys, values)) is the idiomatic way to build a mapping from two lists.
  • zip() objects are iterators: consume once unless you re-create or materialize with list().
  • enumerate() yields (index, value); set start when you need 1-based or custom offsets.
  • Use enumerate(zip(...)) for numbered rows over aligned columns.
Next Topics: We'll cover Python regular expressions with practical patterns