I'm trying to rewrite this:
def flatten(lst): flat =  for x in lst: if hasattr(x, '__iter__') and not isinstance(x, basestring): flat.extend(flatten(x)) else: flat.append(x) return flat In : a=[1, [2, 3, 4, [5, 6]], 7] In : flatten(a) Out: [1, 2, 3, 4, 5, 6, 7]
..into a version that would flatten the iterable, but return values in a lazy manner. Now, this works:
def flat_fugly(s): if iterable(s): for x in s: yield chain.from_iterable(flat_fugly(x)) else: yield takewhile(lambda x: True, [s]) list(islice(chain.from_iterable(flat_fugly(a)), 0, 6)) Out: [1, 2, 3, 4, 5, 6]
But, as the name suggests... Is there a cleaner/better way?
Not to mention that I have to apply
flat_fugly anyway while I'd prefer to have plain iterator (I could wrap it in another function that would use
chain.from_iterable of course, but still if it could be all made to fit in one more elegant function that would be preferable).