How to Flatten a Tuple of Lists to a Tuple in Python
A common data transformation task in Python is flattening a tuple that contains multiple lists into a single, flat tuple. This comes up when working with grouped data, function outputs that return nested structures, or data parsed from external sources.
For example:
- Input:
([5, 6], [6, 7, 8, 9], [3]) - Output:
(5, 6, 6, 7, 8, 9, 3)
This guide covers several approaches to flatten a tuple of lists, from the most efficient to the simplest one-liners.
Using itertools.chain.from_iterable() (Recommended)ā
The chain.from_iterable() function from the itertools module is the most efficient way to flatten a tuple of lists. It lazily iterates through each sublist and yields elements one at a time, without creating intermediate data structures.
from itertools import chain
tup = ([5, 6], [6, 7, 8, 9], [3])
result = tuple(chain.from_iterable(tup))
print(result)
Output:
(5, 6, 6, 7, 8, 9, 3)
chain.from_iterable(tup)takes the tuple of lists and produces a single flat iterator that yields elements from each sublist in sequence.tuple()converts the iterator into a tuple.
chain.from_iterable() is lazy - it doesn't create any intermediate lists in memory. It simply yields one element at a time from each sublist. This makes it the best choice for large datasets where memory efficiency matters.
Using a Generator Expressionā
A generator expression provides a concise and readable alternative that uses familiar Python loop syntax. It works similarly to chain.from_iterable() by producing elements lazily.
tup = ([5, 6], [6, 7, 8, 9], [3])
result = tuple(x for sublist in tup for x in sublist)
print(result)
Output:
(5, 6, 6, 7, 8, 9, 3)
The nested for clauses read left to right:
for sublist in tup- iterates over each list inside the tuple.for x in sublist- iterates over each element inside the current list.x- yields the individual element.
The nested for expressions follow the same order as equivalent nested for loops:
# The generator expression above is equivalent to:
result = []
for sublist in tup:
for x in sublist:
result.append(x)
result = tuple(result)
Using functools.reduce()ā
The reduce() function from the functools module applies a combining function cumulatively across the sublists, concatenating them into a single list.
from functools import reduce
tup = ([5, 6], [6, 7, 8, 9], [3])
result = tuple(reduce(lambda a, b: a + b, tup))
print(result)
Output:
(5, 6, 6, 7, 8, 9, 3)
You can also use operator.add instead of a lambda for cleaner code:
from functools import reduce
import operator
tup = ([5, 6], [6, 7, 8, 9], [3])
result = tuple(reduce(operator.add, tup))
print(result)
Output:
(5, 6, 6, 7, 8, 9, 3)
reduce() and list concatenationEach + operation creates a new intermediate list, copying all previously accumulated elements. For a tuple with n sublists, this results in O(n²) time complexity:
Step 1: [5, 6] + [6, 7, 8, 9] ā new list [5, 6, 6, 7, 8, 9]
Step 2: [5, 6, 6, 7, 8, 9] + [3] ā new list [5, 6, 6, 7, 8, 9, 3]
For small tuples this is fine, but for large data use itertools.chain.from_iterable() instead.
Using sum() with an Empty Listā
A concise one-liner that leverages Python's sum() function. Since sum() uses the + operator and + concatenates lists, it effectively flattens the structure.
tup = ([5, 6], [6, 7, 8, 9], [3])
result = tuple(sum(tup, []))
print(result)
Output:
(5, 6, 6, 7, 8, 9, 3)
The second argument [] serves as the starting value for the summation. Each sublist is concatenated to this accumulator.
While this is the shortest solution, it suffers from the same O(n²) performance issue as reduce() since it creates intermediate lists at every step. Use it only for small datasets.
Using a for Loop with extend()ā
For maximum clarity and control, a traditional for loop with list.extend() is straightforward and avoids the quadratic overhead of list concatenation:
tup = ([5, 6], [6, 7, 8, 9], [3])
flat = []
for sublist in tup:
flat.extend(sublist)
result = tuple(flat)
print(result)
Output:
(5, 6, 6, 7, 8, 9, 3)
extend() adds all elements from the sublist to flat in place, without creating a new list each time. This makes it more efficient than using + concatenation.
Comparison of Approachesā
| Method | Time Complexity | Memory Efficient | Readability | Best For |
|---|---|---|---|---|
itertools.chain.from_iterable() | O(n) | ā (lazy) | āāāā | Large datasets (recommended) |
| Generator expression | O(n) | ā (lazy) | āāāāā | Clean, readable code |
for loop with extend() | O(n) | ā | āāāā | Custom logic, beginners |
functools.reduce() | O(n²) | ā | āāā | Functional programming style |
sum(tup, []) | O(n²) | ā | āāā | Quick one-liners, small data |
Conclusionā
For flattening a tuple of lists into a single tuple, itertools.chain.from_iterable() is the best overall choice. It's efficient, memory-friendly, and handles large datasets gracefully.
- A generator expression is an excellent alternative when you prefer pure Python without imports.
- Avoid
reduce()andsum()with list concatenation for large inputs due to their quadratic performance.
Choose the method that best fits your data size and readability preferences.