It is more efficient to concatenate using itertools.chain
.
>>> m = [[i] for i in range(200)]
>>> m
[[0], [1], [2], [3], [4], [5], [6], [7], [8], ...]
>>> from itertools import *
>>> list(chain(*m))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ...]
Personally, I prefer this over list comprehension as it's hard to remember which for loop comes first. There is even a more efficient variant, list(chain.from_iterable(m))
.
Microbenchmark results (with Python 3 using the timeit
module. A list size of p x q means m = [list(range(q)) for _ in range(p)]
):
list size | chain(*m) | sum(m,[]) | list comp | flatten |
----------+------------+---------------+------------+------------+
2 x 1 | 1.78 µs | 0.646 µs | 0.905 µs | 1.49 µs |
20 x 1 | 4.37 µs | 7.49 µs | 5.19 µs | 3.59 µs |
200 x 1 | 26.9 µs | 134 µs | 40 µs | 24.4 µs |
2000 x 1 | 233 µs | 12.2 ms | 360 µs | 203 µs |
----------+------------+---------------+------------+------------+
2 x 1 | 1.78 µs | 0.646 µs | 0.905 µs | 1.49 µs |
2 x 10 | 2.55 µs | 0.899 µs | 3.14 µs | 2.2 µs |
2 x 100 | 9.07 µs | 2.03 µs | 17.2 µs | 8.55 µs |
2 x 1000 | 51.3 µs | 21.9 µs | 139 µs | 49.5 µs |
----------+------------+---------------+------------+------------+
chain(*m) -> list(chain(*m))
sum(m,[]) -> sum(m, [])
list comp -> [j for i in m for j in i]
flatten -> icfi = chain.from_iterable; list(icfi(m))
It shows that sum
is efficient only when the outer list size is very short. But then you have an even more efficient variant: m[0]+m[1]
.