【问题标题】:How to flatten a list of nested tuples in Python?如何在 Python 中展平嵌套元组列表?
【发布时间】:2018-05-06 00:25:43
【问题描述】:

我有一个如下所示的元组列表:

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

我想把它变成这样:

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

最 Pythonic 的方法是什么?

【问题讨论】:

  • 我不认为这是重复的,因为他想保留这对
  • 确实,我收回了flag
  • 是的,我想保留这对。我可以使用 for 循环中的一些 if 语句轻松做到这一点,但我想知道是否有更好的方法使用列表推导或迭代器
  • 你可以把整个东西压平,然后把剩下的配对:zip(*[iter(L)]*2) from:stackoverflow.com/a/23286332/4834

标签: python list-comprehension flatten


【解决方案1】:

canonical un-flatten recipe 调整为仅在值中有元组时才展开:

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

这只会解开元组,并且仅当其中有其他元组时:

>>> sample = [('a', 'b'), ('c', 'd'), (('e', 'f'), ('h', 'i'))]
>>> list(flatten(sample))
[('a', 'b'), ('c', 'd'), ('e', 'f'), ('h', 'i')]

【讨论】:

    【解决方案2】:

    单行解决方案是使用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')]
    

    【讨论】:

    • 同上:当然,这不会处理任意嵌套。
    【解决方案3】:

    一行,使用列表推导:

    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)
    

    产量:

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

    如果元素不是元组的元组,这是人为地创建一个列表,然后展平所有的工作。为了避免创建单个元素列表[x](x for _ in range(1)) 也可以完成这项工作(虽然它看起来很笨重)

    限制:不能处理超过 1 级的嵌套。在这种情况下,必须编写更复杂/递归的解决方案(检查Martijn's answer)。

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2015-04-13
      • 2012-11-21
      • 1970-01-01
      • 2019-03-05
      • 2018-06-24
      • 1970-01-01
      相关资源
      最近更新 更多