Related values often arrive in separate lists, such as names in one list and scores in another. Python’s zip() function pairs items at matching positions and returns an iterator that yields tuples.

I’ll explain what zip() returns and show how to pair iterables, including how it handles different lengths.

TL;DR: What the Python zip() Function Does

zip() pairs items at matching positions from iterable inputs and returns an iterator that yields tuples.

  • Use list(zip(a, b)) to materialize pairs for display or reuse.
  • By default, pairing stops when the shortest input ends.
  • Use strict=True to reject unequal lengths, or itertools.zip_longest() to pad missing positions.

What Does the Python zip() Function Return?

zip() is a built-in function that accepts zero or more iterables and returns a zip object. Each yielded tuple has one value from each input in iteration order.

An iterable is an object Python can read one item at a time, such as a list, string or dictionary. Convert the result with list() when you need to inspect or reuse all pairs. The iterator is consumed as you read it, so save the resulting list if you need a second pass.

pairs = zip(["tea", "coffee"], [2, 5])
print(type(pairs).__name__)
print(list(pairs))
zip
[('tea', 2), ('coffee', 5)]

With no arguments, zip() yields nothing. With one iterable, each tuple contains one item, as in [(1,), (2,)]. This form helps when a tuple-shaped result matters, though ordinary iteration is simpler for single values.

How to Use zip() to Pair Iterables

zip() is also useful for converting paired fields into records or transposing rows into columns.

Step 1: Pair corresponding values

Pass the source iterables as separate arguments. A for loop unpacks each tuple into descriptive names, then processes that row before moving to the next one.

names = ["Asha", "Ben", "Cara"]
scores = [92, 85, 88]
for name, score in zip(names, scores):
    print(name, score)

Step 2: Build a dictionary from two iterables

Choose dict(zip(keys, values)) when each key should map to the value at the same position. Check both lengths when every value must be represented. Otherwise, the default behavior drops unmatched trailing items.

labels = ["name", "score"]
values = ["Asha", 92]
record = dict(zip(labels, values))
print(record)

Step 3: Unpack pairs into separate iterables

Use the unpacking operator * on a sequence of tuples, then pass those tuples to zip() to regroup first values together and second values together. The output columns are tuples. Convert them to lists if mutation is needed.

rows = [("red", 1), ("blue", 2)]
colors, counts = zip(*rows)
print(colors, counts)

I ran python3 zip_demo.py. The full output follows.

Pairs: [('Asha', 92), ('Ben', 85), ('Cara', 88)]
Record: {'name': 'Asha', 'score': 92}
Colors: ('red', 'blue')
Counts: (1, 2)

The tuples preserve corresponding positions, and unpacking gives one tuple per input column. For another view of tuple-shaped records, see Python lists of tuples.

What Happens When Iterables Have Different Lengths?

Use strict=True when every row must match, and zip_longest() when unpaired values still belong in the result.

Need Use Result
Stop at shortest input zip(a, b) Extra trailing items are omitted
Require equal lengths (Python 3.10+) zip(a, b, strict=True) Raises ValueError for a mismatch
Keep every item itertools.zip_longest(a, b, fillvalue=None) Fills missing positions through the longest input
from itertools import zip_longest

left = ["A", "B", "C"]
right = [10, 20]
print(list(zip(left, right)))
print(list(zip_longest(left, right, fillvalue="?")))
[('A', 10), ('B', 20)]
[('A', 10), ('B', 20), ('C', '?')]

Use zip_longest() only when retaining the unmatched item is part of the task. Also avoid unzipping an empty sequence: zip(*[]) produces no columns, so unpacking it into two variables raises a ValueError.

Ordinary iteration is clearer for one list. When multiple lists hold related fields, zip() pairs values together during each loop iteration.

Common zip() Errors and What to Check

Common zip() problems come from unexpected input lengths, exhausted iterators or arguments that are not iterable. Check the call signature first, then match the symptom to the appropriate fix.

Check the syntax and arguments

The signature is zip(*iterables, strict=False). Each argument must be iterable. The asterisk denotes a variable number of inputs, while strict is a keyword-only option available in Python 3.10 and later.

Parameter Meaning Effect
*iterables Zero or more iterable inputs One item from each input forms each output tuple
strict Keyword-only boolean, default False When True, raises ValueError if input lengths differ

For example, zip([“id”, “name”], [7, “Mina”]) yields pairs that dict() can turn into a record. Choose strict=True when unmatched data signals a bug, rather than silently accepting a shortened result.

Handle common mistakes

Case Symptom Fix
Only one input is passed Each result is a one-item tuple Pass another iterable or unpack each tuple explicitly
Inputs have unequal lengths Default zip() omits unmatched tail items Use strict=True to detect mismatch or zip_longest() to pad
Iterator is reused after conversion A second pass produces no pairs Store list(zip(…)) when repeated access is required

When unzipping rows, check that at least one row exists before assigning columns. An empty input has no first tuple from which Python can infer the number of columns, so unpacking zip(*rows) into named variables raises ValueError.

Conclusion: Choose the Right zip() Behavior

Choose the length policy that matches your data contract: truncate when extra values are irrelevant, validate when they indicate an error, or pad when they must remain visible.

For related reading, see Python lists of tuples and the guide to iterating through a list. The official zip() documentation gives the full signature.

FAQ

These answers cover common questions about the function’s return value and input lengths.

What does zip() return in Python?

It returns a zip object, an iterator that yields tuples with one value from each input iterable.

How do you create a dictionary with zip()?

Pass the keys and values iterables to dict(zip(keys, values)). Matching positions become key-value pairs.

Does zip() require iterables to have equal lengths?

No. By default it stops at the shortest input. Use strict=True to raise ValueError on unequal lengths, or itertools.zip_longest() to pad missing values.

Share.
Leave A Reply