'flatten nested iterables --- is my helper class necessary

i wanted to flatten a nested structure of iterables into a simple list. To do this I have written a function flatten_nested_iterator and a class IterableFromIterator (see below).

Some questions came up but manly I wonder if my helper class needed? I came up with it since from my knowledge every iterator is also an iterable, but not every iterable is an iterator.

I could potentially also just add:

if not hasattr(rest, '__iter__'):
    rest.__iter__ = lambda self: self

Would you consider this to be a better solution? Maybe less understandable.

Also is this maybe way to complicated and there is an easier solution? What about performance of this approach? I don't care too much in my specific use case; mostly my resulting list will have fewer than 10 elements but is is interesting nevertheless.

Grateful for any feedback.


code:

class IterableFromIterator:
    """Converts an iterator into an iterable by defining a trivial `__iter__`
    method."""

    def __init__(self, iterator):
        self.iterator = iterator

    def __iter__(self):
        return self

    def __next__(self):
        return next(self.iterator)


def flatten_nested_iterables(iterable):
    """Convertes a nested structure of iterables into a flat list.

    Examples
    ========
    >>> import numpy as np
    >>> flatten_nested_iterables([[1, 2, [3]], 4, [5, 6], (2,2),
    ...                           np.array([3, 3]), np.ones((2,2))])
    ...
    [1, 2, 3, 4, 5, 6, 2, 2, 3, 3, 1.0, 1.0, 1.0, 1.0]
    """

    iterator = iter(iterable)
    try:
        first = next(iterator)
    except StopIteration:
        return []

    rest = IterableFromIterator(iterator)

    if hasattr(first, '__iter__'):
        return flatten_nested_iterables(first) + flatten_nested_iterables(rest)

    return [first] + flatten_nested_iterables(rest)


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source