If you don't like/want such behavior, you can use the following version which filters out from flattening iterables like strings and bytes: def flatten(itr): since ALL iterables are flattened, strings are decomposed into sequences of single characters. versatile (you can use it to build an iterable of your choice or in a loop).efficient (you can flatten the nested iterable partially, without wasting time on the remaining part you don't need).
works also if top level contains bare items.works with any combination and deepness of nesting.works with any kind of iterable (even future ones!).Usage: this is a generator, you typically want to enclose it in an iterable builder like list() or tuple() or use it in a for loop. There are several answers with the same recursive appending scheme as below, but none makes use of try, which makes the solution more robust and Pythonic. In Python 3.8, abstract base classes are moved from collection.abc to the typing module.ĭemo simple =, ,, ]Ĭomplicated = ], (3, 4, ,ġ Disclaimer: I'm the author of that library.In Python 3, yield from flatten(x) can replace for sub_x in flatten(x): yield sub_x.If isinstance(x, Iterable) and not isinstance(x, (str, bytes)): """Yield items from any nested iterable see Reference.""" #from collections import Iterable # < p圓8 This can flatten both simple and complicated containers (see also Demo). Here is a general approach that applies to numbers, strings, nested lists and mixed containers. Return functools.reduce(operator.iconcat, a, ) If the number of sublists is large, this performs a little worse than the above suggestion.Ĭode to reproduce the plot: import functools ( operator.iadd is equally fast.)Ī simpler and also acceptable variant is out = To be the fastest solution, both when many small lists and few long lists are concatenated.
I tested most suggested solutions with perfplot (a pet project of mine, essentially a wrapper around timeit), and found import functoolsįunctools.reduce(operator.iconcat, a, ) 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. 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. $ python -mtimeit -s't=,, ]*99' 'reduce(lambda x,y: x+y,t)'Įxplanation: the shortcuts 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). Return Īs evidence, you can use the timeit module in the standard library: $ python -mtimeit -s't=,, ]*99' ''ġ0000 loops, best of 3: 143 usec per loop Here is the corresponding function: def flatten(t): Is faster than the shortcuts posted so far.