You wrote [a[i] + b[i] for i in range(len(a))] and got IndexError because list b is shorter than a. Or you nested loops and the inner list had a different length than expected. List comprehensions don’t fail more often than regular loops, but the one-liner format hides the bug until runtime.

📌 Quick answer: Replace for i in range(len(a)) with zip(a, b) when iterating two lists in parallel. zip auto-stops at the shorter list. For positional access use enumerate. Both prevent the most common comprehension IndexError patterns.
Cause 1: Mismatched parallel lists with range(len(a))
The most common bug pattern.
a = [1, 2, 3, 4, 5]
b = [10, 20, 30]
# ❌ IndexError on b[3]
result = [a[i] + b[i] for i in range(len(a))]
# ✓ zip auto-stops at shorter list
result = [x + y for x, y in zip(a, b)] # [11, 22, 33]Cause 2: Nested loop accessing outer list by index
Common in 2D matrix code.
matrix = [[1, 2], [3, 4, 5], [6]]
# ❌ matrix[1] has 3 items, matrix[2] has 1
flat = [matrix[i][j] for i in range(3) for j in range(2)]
# ✓ iterate inner lists directly
flat = [item for row in matrix for item in row]Cause 3: Conditional access on possibly-empty inner list
The conditional comes too late, after the index.
data = [{"items": [1, 2]}, {"items": []}, {"items": [9]}]
# ❌ data[1]["items"][0] doesn't exist
firsts = [d["items"][0] for d in data]
# ✓ guard inside the comprehension
firsts = [d["items"][0] for d in data if d["items"]]Prevention
- Use zip() for parallel iteration, never
for i in range(len(a)) - Use enumerate(items) for “index + value” instead of range(len)
- Add an
ifclause inside comprehension to filter out empty/missing rows - Test with mismatched / empty inputs in unit tests
Related Guides
- List index out of range (full guide)
- String index out of range
- All IndexError fixes
- Python Tutorial hub
Frequently Asked Questions
Why use zip() instead of range(len())?
zip auto-handles different-length inputs by stopping at the shorter one. range(len(a)) only knows about a’s length and will index out of b if b is shorter. zip is also more readable and Pythonic.
How do I iterate with index and value together?
Use enumerate(items): for i, v in enumerate(items). It’s cleaner than for i in range(len(items)) and avoids the IndexError trap when items length changes between iterations.
Can I add a try/except inside a list comprehension?
Not directly; comprehensions don’t support try/except. Refactor to a helper function: def safe(d, k): try: return d[k][0]; except (IndexError, KeyError): return None. Then [safe(d, ‘items’) for d in data].
How do I flatten a 2D list safely?
[item for row in matrix for item in row]. The two for clauses iterate the structure directly, no indexing required, never raises IndexError.
What’s the difference between zip and itertools.zip_longest?
zip stops at the shortest input. zip_longest continues to the longest, padding shorter inputs with a fillvalue (default None). Use zip when shorter is acceptable, zip_longest when you need every element from the longest.
