I have an arbitrarily nested iterable like so:
numbers = (1, 2, (3, (4, 5)), 7)
and I\'d like to map a function over it without changing the st
Everyone before has mentioned the number of things one might possibly need for any flavour of a flatten
function, but there was something that I've been playing with as an exercise in learning the language (so Python noob alert) that I didn't see quite put together here. Basically I wanted for my flatten
to be able to handle any Iterable
s, of any length and nesting in the most efficient (time and space) way possible. This lead me to the generator pattern, and the first requirement I posed for my function was nothing to be created before its time.
My other requirement was the absence of any explicit looping (for/while) because why not: at least since the helpful addition of yield from
in Python 3.3 I was pretty sure it was possible. It would have to be recursive of course, but getting it to give a proper, "flat" generator proved trickier than I thought. So here's my 2p, illustrating the wonderful chain
and, I suspect, the kind of situation (a bit more abstracted of course) it was made for:
from itertools import chain
from collections import Iterable
def flatten(items):
if isinstance(items,Iterable):
yield from chain(*map(flatten,items))
else:
yield items
items = [0xf, [11, 22, [23, (33,(4, 5))], 66, [], [77]], [8,8], 99, {42}]
print(list(flatten(items)))
Unfortunately for my for-free ambitious project (and ego), according to some pretty rough benchmarking this is ~30% slower than the version using for
:
def flatten(items):
for item in items:
if isinstance(item,Iterable):
yield from flatten(item)
else:
yield item
a variant of which was already given by Uriel. I hope it is however a good illustration of the flexibility and power of Python used in a quasi-functional way, especially for others new to the language.
Edit: to avoid splitting up strings in individual list items, one can append and not isinstance(item,(str,bytes))
to the conditional. And other various bells and whistles that would detract from the point.