How to flatten a list of nested tuples in Python?

前端 未结 3 553
自闭症患者
自闭症患者 2020-12-10 19:39

I have a list of tuples that looks like this:

[(\'a\', \'b\'), (\'c\', \'d\'), ((\'e\', \'f\'), (\'h\', \'i\'))]

I want to turn it into thi

相关标签:
3条回答
  • 2020-12-10 19:53

    Adjust the canonical un-flatten recipe to only unflatten when there are tuples in the value:

    def flatten(l):
        for el in l:
            if isinstance(el, tuple) and any(isinstance(sub, tuple) for sub in el):
                for sub in flatten(el):
                    yield sub
            else:
                yield el
    

    This will only unwrap tuples, and only if there are other tuples in it:

    >>> sample = [('a', 'b'), ('c', 'd'), (('e', 'f'), ('h', 'i'))]
    >>> list(flatten(sample))
    [('a', 'b'), ('c', 'd'), ('e', 'f'), ('h', 'i')]
    
    0 讨论(0)
  • 2020-12-10 20:01

    one-line, using list comprehension:

    l = [('a', 'b'), ('c', 'd'), (('e', 'f'), ('h', 'i'))]
    
    result = [z for y in (x if isinstance(x[0],tuple) else [x] for x in l) for z in y]
    
    print(result)
    

    yields:

    [('a', 'b'), ('c', 'd'), ('e', 'f'), ('h', 'i')]
    

    this is artificially creating a list if the element is not a tuple of tuples, then flattening all does the job. To avoid creating a single element list [x], (x for _ in range(1)) can also do the job (although it appears clunky)

    Limitation: doesn't handle more than 1 level of nesting. In which case, a more complex/recursive solution must be coded (check Martijn's answer).

    0 讨论(0)
  • 2020-12-10 20:17

    A one-line solution would be using itertools.chain:

    >>> l = [('a', 'b'), ('c', 'd'), (('e', 'f'), ('h', 'i'))]
    >>> from itertools import chain
    >>> [*chain.from_iterable(x if isinstance(x[0], tuple) else [x] for x in l)]
    [('a', 'b'), ('c', 'd'), ('e', 'f'), ('h', 'i')]
    
    0 讨论(0)
提交回复
热议问题