Question (Issue)
I want to flatten this list of lists:
[[1, 2, 3], [4, 5, 6], [7], [8, 9]]
into:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Now we will see Solution for issue: How do I make a flat list out of a list of lists?
Answer (solution)
To flatten a list of lists xss
:
flat_list = [x for xs in xss for x in xs]
This is equivalent to:
flat_list = []
for xs in xss:
for x in xs:
flat_list.append(x)
Or as a function:
def flatten(xss):
return [x for xs in xss for x in xs]
Performance analysis:
To measure performance, we use the timeit
module from the standard library:
$ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[x for xs in xss for x in xs]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(t, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,t)'
1000 loops, best of 3: 1.1 msec per loop
Explanation: the methods based on +
(including the implied use in sum
) are, of necessity, O(T**2)
when there are T sublists — as the intermediate result list keeps getting longer, at each step a new intermediate result list object gets allocated, and all the items in the previous intermediate result must be copied over (as well as a few new ones added at the end). So, for simplicity and without actual loss of generality, say you have T sublists of k items each: the first k items are copied back and forth T-1 times, the second k items T-2 times, and so on; total number of copies is k times the sum of x for x from 1 to T excluded, i.e., k * (T**2)/2
.
The list comprehension just generates one list, once, and copies each item over (from its original place of residence to the result list) also exactly once.
This question is answered By – Alex Martelli
This answer is collected from stackoverflow and reviewed by FixPython community admins, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0