如何将包含不同数据类型(整数、元组)的列表展开(平铺)?

9
假设我有一个包含一个或多个元组的列表:
[0, 2, (1, 2), 5, 2, (3, 5)]

什么是消除元组以使其成为整数列表的最佳方法?
[0, 2, 1, 2, 5, 2, 3, 5]

可能是 Flattening a shallow list in Python 的重复问题。 - Russia Must Remove Putin
2
并不是那个问题的重复,因为并非每个内部元素都是元组。 - Andrew Clark
那么请考虑下面我的递归解决方案! :) - Russia Must Remove Putin
以下答案可行,但在您将其中一个替换为代码之前,请问自己为什么首先要有这样的列表。如果您可以使原始列表同质化,那么您的代码将更易于理解。 - mgilson
是的,而且请考虑到我的通用解决方案适用于任何数据类型和任何深度。 :) - Russia Must Remove Putin
5个回答

6

以下是其中一种解决方案(使用itertools.chain):

>>> from itertools import chain
>>> l = [0, 2, (1, 2), 5, 2, (3, 5)]
>>> list(chain(*(i if isinstance(i, tuple) else (i,) for i in l)))
[0, 2, 1, 2, 5, 2, 3, 5]

5

使用嵌套列表推导:

>>> lst = [0, 2, (1, 2), 5, 2, (3, 5)]
>>> [y for x in lst for y in (x if isinstance(x, tuple) else (x,))]
[0, 2, 1, 2, 5, 2, 3, 5]

1
你可以使用我的 funcy 库中的 flatten 函数:
from funcy import flatten
flat_list = flatten(your_list)

你还可以查看其实现方式

1
def untuppleList(lst):
    def untuppleList2(x):
        if isinstance(x, tuple):
            return list(x)
        else:
            return [x]
    return [y for x in lst for y in untuppleList2(x)]

然后您可以执行untuppleList([0, 2, (1, 2), 5, 2, (3, 5)])


1

更通用的递归解决方案,适用于任何可迭代对象(除了字符串)和任何深度的元素:

import collections

def flatten(iterable):
    results = []
    for i in iterable:
        if isinstance(i, collections.Iterable) and not isinstance(i, basestring):
            results.extend(flatten(i))
        else:
            results.append(i)
    return results

使用方法:

>>> flatten((1, 2, (3, 4), ('happy')))
[1, 2, 3, 4, 'happy']
>>> flatten((1, 2, (3, 4, (5, 6)), ('happy'), {'foo': 'bar', 'baz': 123}))
[1, 2, 3, 4, 5, 6, 'happy', 'foo', 'baz']

我会选择ndpu的答案,因为它更适合我的特定数据集,但我可以看出你的解决方案作为一种通用方法非常有用。 - covariance

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接