Search code examples
pythonlistnested-listspython-itertoolschain

Is there a way of avoiding so many list(chain(*list_of_list))?


If I have a list of list of list of tuples of two strings. I want to flatten it out to a non-nested list of tuples, I could do this:

>>> from itertools import chain
>>> lst_of_lst_of_lst_of_tuples = [ [[('ab', 'cd'), ('ef', 'gh')], [('ij', 'kl'), ('mn', 'op')]], [[('qr', 'st'), ('uv', 'w')], [('x', 'y'), ('z', 'foobar')]] ]
>>> lllt = lst_of_lst_of_lst_of_tuples
>>> list(chain(*list(chain(*lllt))))
[('ab', 'cd'), ('ef', 'gh'), ('ij', 'kl'), ('mn', 'op'), ('qr', 'st'), ('uv', 'w'), ('x', 'y'), ('z', 'foobar')]

But is there another way of unpacking to the non-nested list of tuples withou the nested list(chain(*lst_of_lst))?


Solution

  • You could keep unpacking until you hit tuples:

    def unpack_until(data, type_):
        for entry in data:
            if isinstance(entry, type_):
                yield entry
            else:
                yield from unpack_until(entry, type_)
    

    Then:

    >>> list(unpack_until(lllt, tuple))
    [('ab', 'cd'),
     ('ef', 'gh'),
     ('ij', 'kl'),
     ('mn', 'op'),
     ('qr', 'st'),
     ('uv', 'w'),
     ('x', 'y'),
     ('z', 'foobar')]