Skip to content

How to Zip Two Lists of Lists in Python

Learn how to pair, concatenate, or interleave two lists of lists in Python using zip(), zip_longest(), list comprehensions, and NumPy for handling nested data structures.

The built-in zip() function pairs elements from multiple iterables, but when working with lists of lists (nested lists), you often need more control over how sublists are combined. Depending on your use case, you might want to pair sublists as tuples, concatenate them into longer lists, or handle unequal lengths gracefully.

In this guide, you will learn multiple methods to zip two lists of lists in Python, from simple zip() usage to handling unequal lengths and merging sublists.

Understanding the Different "Zip" Operations

There are several ways to combine two lists of lists, and it's important to understand what each produces:

list1 = [[1, 2], [3, 4], [5, 6]]
list2 = [[7, 8], [9, 10], [11, 12]]
Operation Result Description
Pair as tuples [([1,2], [7,8]), ...] Each pair is a tuple of two sublists
Concatenate [[1,2,7,8], ...] Sublists merged into longer lists
Element-wise merge [[1,7,2,8], ...] Elements interleaved

The simplest approach uses zip() to pair corresponding sublists from both lists:

list1 = [[1, 2], [3, 4], [5, 6]]
list2 = [[7, 8], [9, 10], [11, 12]]

result = list(zip(list1, list2))

print(result)

Output:

[([1, 2], [7, 8]), ([3, 4], [9, 10]), ([5, 6], [11, 12])]

Each result element is a tuple containing the corresponding sublists from both input lists.

Using List Comprehension for Clarity

list1 = [[1, 2], [3, 4], [5, 6]]
list2 = [[7, 8], [9, 10], [11, 12]]

result = [(a, b) for a, b in zip(list1, list2)]

print(result)

Output:

[([1, 2], [7, 8]), ([3, 4], [9, 10]), ([5, 6], [11, 12])]

Method 2: Concatenating Sublists

To merge corresponding sublists into single longer lists, use the + operator inside a comprehension:

list1 = [[1, 2], [3, 4], [5, 6]]
list2 = [[7, 8], [9, 10], [11, 12]]

result = [a + b for a, b in zip(list1, list2)]

print(result)

Output:

[[1, 2, 7, 8], [3, 4, 9, 10], [5, 6, 11, 12]]

This is often the desired behavior: combining related data from two sources into unified lists.

Concatenating More Than Two Lists

list1 = [[1, 2], [3, 4]]
list2 = [[5, 6], [7, 8]]
list3 = [[9, 10], [11, 12]]

result = [a + b + c for a, b, c in zip(list1, list2, list3)]

print(result)

Output:

[[1, 2, 5, 6, 9, 10], [3, 4, 7, 8, 11, 12]]

Method 3: Handling Unequal Lengths with zip_longest()

Standard zip() stops at the shortest list, silently dropping elements from longer lists:

list1 = [[1, 2], [3, 4]]
list2 = [[5, 6], [7, 8], [9, 10]]

result = list(zip(list1, list2))
print(result)

Output:

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

Use itertools.zip_longest() to include all elements, filling missing values with a default:

from itertools import zip_longest

list1 = [[1, 2], [3, 4]]
list2 = [[5, 6], [7, 8], [9, 10]]

result = list(zip_longest(list1, list2, fillvalue=[]))

print(result)

Output:

[([1, 2], [5, 6]), ([3, 4], [7, 8]), ([], [9, 10])]

Concatenating with zip_longest()

from itertools import zip_longest

list1 = [[1, 2], [3, 4]]
list2 = [[5, 6], [7, 8], [9, 10]]

result = [a + b for a, b in zip_longest(list1, list2, fillvalue=[])]

print(result)

Output:

[[1, 2, 5, 6], [3, 4, 7, 8], [9, 10]]

Method 4: Element-Wise Interleaving

To interleave elements from corresponding sublists (alternating between them):

list1 = [[1, 2], [3, 4]]
list2 = [[5, 6], [7, 8]]

result = []
for a, b in zip(list1, list2):
    interleaved = [val for pair in zip(a, b) for val in pair]
    result.append(interleaved)

print(result)

Output:

[[1, 5, 2, 6], [3, 7, 4, 8]]

Compare with concatenation:

Concatenated:  [[1, 2, 5, 6], [3, 4, 7, 8]]
Interleaved:   [[1, 5, 2, 6], [3, 7, 4, 8]]

Method 5: Using a Loop

An explicit loop provides maximum clarity and is easy to extend with custom logic:

list1 = [[1, 3], [4, 5], [5, 6]]
list2 = [[7, 9], [3, 2], [3, 10]]

result = []
for i in range(len(list1)):
    result.append(list1[i] + list2[i])

print(result)

Output:

[[1, 3, 7, 9], [4, 5, 3, 2], [5, 6, 3, 10]]

Method 6: Using NumPy for Large Numeric Data

For large numeric datasets, NumPy provides optimized array operations:

import numpy as np

list1 = [[1, 2], [3, 4], [5, 6]]
list2 = [[7, 8], [9, 10], [11, 12]]

arr1 = np.array(list1)
arr2 = np.array(list2)

paired = np.stack([arr1, arr2], axis=1)
print("Paired:\n", paired)

concatenated = np.concatenate([arr1, arr2], axis=1)
print("\nConcatenated:\n", concatenated)

summed = arr1 + arr2
print("\nElement-wise sum:\n", summed)

Output:

Paired:
 [[[ 1  2]
  [ 7  8]]

 [[ 3  4]
  [ 9 10]]

 [[ 5  6]
  [11 12]]]

Concatenated:
 [[ 1  2  7  8]
 [ 3  4  9 10]
 [ 5  6 11 12]]

Element-wise sum:
 [[ 8 10]
 [12 14]
 [16 18]]

Common Mistake: Unexpected Truncation with zip()

A frequent bug is not realizing that zip() silently truncates to the shortest input:

Problem

list1 = [[1, 2], [3, 4], [5, 6]]
list2 = [[7, 8], [9, 10]]

result = [a + b for a, b in zip(list1, list2)]
print(result)

Output:

[[1, 2, 7, 8], [3, 4, 9, 10]]

Fix: use zip_longest() or validate lengths

from itertools import zip_longest

list1 = [[1, 2], [3, 4], [5, 6]]
list2 = [[7, 8], [9, 10]]

result = [a + b for a, b in zip_longest(list1, list2, fillvalue=[])]
print(result)  # [[1, 2, 7, 8], [3, 4, 9, 10], [5, 6]]

if len(list1) != len(list2):
    print(f"Warning: lists have different lengths ({len(list1)} vs {len(list2)})")

Output:

[[1, 2, 7, 8], [3, 4, 9, 10], [5, 6]]
Warning: lists have different lengths (3 vs 2)

Comparison of Methods

Method Operation Handles Unequal Lengths Best For
zip() + tuples Pair sublists ❌ Truncates Simple pairing
zip() + concatenation Merge sublists ❌ Truncates Combining related data
zip_longest() Pair/merge with fill ✅ Yes Unequal-length lists
Loop Custom merging ⚠️ Manual check Complex logic, debugging
NumPy Array operations ❌ Requires same shape Large numeric datasets

Summary

Zipping two lists of lists in Python can mean different things depending on your needs. Key takeaways:

  • Use zip() to pair corresponding sublists: the simplest and most common approach.
  • Use a + b in a comprehension to concatenate sublists into longer lists.
  • Use zip_longest() when lists have different lengths to avoid silent data loss.
  • Use NumPy for large numeric datasets where performance matters.
  • Be aware that zip() truncates to the shortest input: always verify list lengths or use zip_longest() when lengths might differ.
Navigation