All functions measured by a line %timeit some_function(l) are measured incorrectly. A time in about hundreds of nanoseconds to get a list of 9 * 1000 numbers is a nonsense. You will see that the result doesn't depend on a number of items.
It is because any code after a yield command is postponed until you enumerate the output values. If you put a slow sleep command after a yield line then you will see no difference because it run never. Even a generator expression command %timeit (x for x in range(1000000000)) is similarly fast as the same for range(1).
A correct measurement is by %timeit list(some_function(l)) or %timeit for _ in some_function(l): pass
The fastest code for flattening is flatten_chain(l) because the expression itertools.chain(*lst) uses only a library function call and no Python loops.
Here's a different, non recursive, solution for deep flattening:
def flatten(bad):
good = []
while bad:
e = bad.pop()
if isinstance(e, list):
bad.extend(e)
else:
good.append(e)
return good[::-1]
Very likely quite fast as well.
Great article!!
By the way, is it typo?
def flatten_recursive(lst: List[Any]) -> Iterable[Any]:
"""Flatten a list using recursion."""
for item in lst:
if isinstance(item, list):
yield from flatten(item) # This line! I think it will be `yield from flatten_recursive(item)`
else:
yield item
Gyansetu
Gyansetu's Python section is a Python enthusiast's sanctuary! Their in-depth tutorials and insights provide invaluable guidance for Python learners and professionals alike. Thank you for nurturing our Python prowess! For more info:- gyansetu.in/blogs/future-scope-of-python-in-india