How to Flatten a List of Lists With a for Loop |
steps using a for loop
matrix = [ [9, 3, 8, 3], [4, 5, 2, 8], [6, 4, 3, 1], [1, 0, 4, 5], ]recursive function to flatten a list of lists def flatten_extend(matrix): flat_list = [] for row in matrix: flat_list.extend(row) return flat_listflat_list.extend(row) is the same as flat_list += row
|
Using a Comprehension to Flatten a List of Lists |
core syntax of a list comprehension
[expression(item) for item in iterable]components
def flatten_comprehension(matrix): return [item for row in matrix for item in row]two nested for clauses
|
Flattening a List Using Standard-Library and Built-in Tools |
can use any of these tools
Chaining Iterables With itertools.chain()
the chain() function chains multiple iterables into a single oneinstead of returning a list, chain() returns an iterator which yields items from all the input iterables until they get exhausted can take advantage of chain() along with list() to flatten a list of lists >>>from itertools import chain >>>def flatten_chain(matrix): ... return list(chain.from_iterable(matrix)) ... >>>matrix = [ ... [9, 3, 8, 3], ... [4, 5, 2, 8], ... [6, 4, 3, 1], ... [1, 0, 4, 5], ... ] >>>flatten_chain(matrix) [9, 3, 8, 3, 4, 5, 2, 8, 6, 4, 3, 1, 1, 0, 4, 5]chain is implemented as a class .from_iterable() is a class method method provides an alternative constructor can use alternative c'tor to build a chain from an iterable of iterables builds a list out of the iterator that .from_iterable() returns
Concatenating Lists With functools.reduce()
the reduce() function from the functools module is another tool which can
be used to flatten lists of listsreduce() takes a pair of items and computes a partial result then it uses that result and the next item to compute the next partial result process creates an implicit accumulator that stores the cumulative value in every step
can use different function-like objects with reduce() to flatten a list of lists >>> from functools import reduce >>> def flatten_reduce_lambda(matrix): ... return list(reduce(lambda x, y: x + y, matrix, [])) ... >>> matrix = [ ... [9, 3, 8, 3], ... [4, 5, 2, 8], ... [6, 4, 3, 1], ... [1, 0, 4, 5], ... ] >>> flatten_reduce_lambda(matrix) [9, 3, 8, 3, 4, 5, 2, 8, 6, 4, 3, 1, 1, 0, 4, 5]reduce arguments
can use the following functions from the operator module
Using sum() to Concatenate Lists
use sum() to concatenate the sublists in matrix
>>> def flatten_sum(matrix): ... return sum(matrix, []) ... >>> matrix = [ ... [9, 3, 8, 3], ... [4, 5, 2, 8], ... [6, 4, 3, 1], ... [1, 0, 4, 5], ... ] >>> flatten_sum(matrix) [9, 3, 8, 3, 4, 5, 2, 8, 6, 4, 3, 1, 1, 0, 4, 5] |
Considering Performance While Flattening Lists |
a small script to test how quickly the different approaches can flatten lists of lists
from functools import reduce from itertools import chain from operator import add, concat, iconcat def flatten_extend(matrix): flat_list = [] for row in matrix: flat_list.extend(row) return flat_list def flatten_concatenation(matrix): flat_list = [] for row in matrix: flat_list += row return flat_list def flatten_comprehension(matrix): return [item for row in matrix for item in row] def flatten_chain(matrix): return list(chain.from_iterable(matrix)) def flatten_reduce_lambda(matrix): return list(reduce(lambda x, y: x + y, matrix, [])) def flatten_reduce_add(matrix): return reduce(add, matrix, []) def flatten_reduce_concat(matrix): return reduce(concat, matrix, []) def flatten_reduce_iconcat(matrix): return reduce(iconcat, matrix, []) def flatten_sum(matrix): return sum(matrix, [])performance.py from timeit import timeit import flatten SIZE = 1000 TO_MS = 1000 NUM = 10 FUNCTIONS = [ "flatten_extend", "flatten_concatenation", "flatten_comprehension", "flatten_chain", "flatten_reduce_lambda", "flatten_reduce_add", "flatten_reduce_concat", "flatten_reduce_iconcat", "flatten_sum", ] matrix = [list(range(SIZE))] * SIZE results = { func: timeit(f"flatten.{func}(matrix)", globals=globals(), number=NUM) for func in FUNCTIONS } print(f"Time to flatten a {SIZE}x{SIZE} matrix (in milliseconds):\n") for func, time in sorted(results.items(), key=lambda result: result[1]): print(f"{func + '()':.<30}{time * TO_MS / NUM:.>7.2f} ms")output $ python performance.py Time to flatten a 1000x1000 matrix (in milliseconds): flatten_concatenation()..........1.95 ms flatten_extend().................2.03 ms flatten_reduce_iconcat().........2.68 ms flatten_chain()..................4.60 ms flatten_comprehension()..........7.79 ms flatten_sum().................1113.22 ms flatten_reduce_concat().......1117.15 ms flatten_reduce_lambda().......1117.52 ms flatten_reduce_add()..........1118.80 ms |
Flattening Python Lists for Data Science With NumPy |
flattening a numpy array of arrays (Python list of lists)
>>> import numpy as np >>> matrix = np.array( ... [ ... [9, 3, 8, 3], ... [4, 5, 2, 8], ... [6, 4, 3, 1], ... [1, 0, 4, 5], ... ] ... ) >>> matrix array([[9, 3, 8, 3], [4, 5, 2, 8], [6, 4, 3, 1], [1, 0, 4, 5]]) >>> matrix.flatten() array([9, 3, 8, 3, 4, 5, 2, 8, 6, 4, 3, 1, 1, 0, 4, 5]) |