如何在Python中展开元组

28

我有一个列表元素,而且这个列表有100个元素。

[(50, (2.7387451803816479e-13, 219))]

我该如何将每个元素转换为这样的格式?

[(50, 2.7387451803816479e-13, 219)]

问题没有明确定义。每个元素是否具有相同的结构?需要处理哪种类型的结构?此外,问题真正关注的是如何转换列表的单个元素,还是关于如何重复该过程以处理每个元素?如果两者都涉及到,那就是两个问题 - “对列表的每个元素重复一个过程”通常不取决于该过程是什么。 - Karl Knechtel
7个回答

20

5
这个回答中的链接究竟如何帮助解决这个问题? - GreenAsJade
10
当你了解元组结构时,这是可行的,但有时需要对其进行展平的原因是因为其结构未知。例如,np.where可能会返回包含单个值或值列表的元组,在这种情况下,需要以不同的方式访问元组。如何处理这种情况? - DanGoodrick
@DanGoodrick:np.where不会这样做。元组永远不包含列表;它始终是numpy数组的元组,除了0维数组的奇怪边缘情况外,数组的数量始终等于输入数组的维数。没有必要在不同情况下以不同方式访问元组,将其展平也没有太多意义。 - user2357112
哇,我希望Python能够更加高级一些。 - undefined

15

在Python 3.5中,通过PEP 448引入了额外的元组解包功能,您可以在元组字面值中使用星号表达式,以便您可以使用

>>> l = [(50, (2.7387451803816479e-13, 219)), (40, (3.4587451803816479e-13, 220))]
>>> [(a, *rest) for a, rest in l]
[(50, 2.738745180381648e-13, 219), (40, 3.458745180381648e-13, 220)]

这可能很有用,如果你有一个用于记录许多元素的嵌套元组,并且你想要将其展平。

6
你可以使用以下函数,并将其应用于列表中的每个元素。
def flatten(data):
    if isinstance(data, tuple):
        if len(data) == 0:
            return ()
        else:
            return flatten(data[0]) + flatten(data[1:])
    else:
        return (data,)

工作原理:

  • 首先检查类型是否为元组,如果不是,则将其“转化”为元组。
  • 第二行返回一个空元组,如果元组为空。
  • 第三行获取第一个元素并递归调用函数。

这个解决方案的优点是:

  • 不需要知道给定元组的结构。
  • 元组可以任意嵌套。
  • 在Python 2.2+(以及可能更早的版本)中都可用。

这段代码略有改动,来自以下来源:
https://mail.python.org/pipermail/tutor/2001-April/005025.html

希望能对某些人有所帮助 :)


4
一个比@sagacity答案更好的改进,这将重新运行使用递归yield扁平化元组的生成器。
def flatten(data):
    if isinstance(data, tuple):
        for x in data:
            yield from flatten(x)
    else:
        yield data

要转换为listtuple,请使用list()tuple()
list(flatten(nested_tuple))
tuple(flatten(nested_tuple))

如果需要在 Python 2 中使用,请将yield from替换为另一个循环。
def flatten(data):
    if isinstance(data, tuple):
        for x in data:
            for y in flatten(x):
                yield y
    else:
        yield data

2
Python 2.7兼容的方式,实现Mitch在Python 3.5中建议的方法。
>>> example =  [(50, (2.7387451803816479e-13, 219)),
            (100, (3.7387451803816479e-13, 218))]
>>> [(lambda *x: x)(k, *r) for k, r in example]
[(50, 2.738745180381648e-13, 219), (100, 3.7387451803816477e-13, 218)]

这种方法的优点在于,您不必为要展开的内部元组的每个值找到一个变量名称,就像在被接受的答案中那样。如果有两个或三个项,那并不是真正的问题,但想象一下有十个或更多的值...

1
您可以这样获得结果。
>> example =  [(50, (2.7387451803816479e-13, 219))]
>>> [tuple(x[:1]) + (x[1]) for x in example] 
[(50, 2.738745180381648e-13, 219)]

0
这段代码适用于嵌套元组。
def flatten(args):
    try:
        iter(args)
        final = []
        for arg in args:
            final += flatten(arg)
        return tuple(final)
    except TypeError:
        return (args, )

flatten([1, 2, 3, 4])  # (1, 2, 3, 4)
flatten([1, [2, 3], 4])  # (1, 2, 3, 4)
flatten([1, [2, [3]], [[4]]])  # (1, 2, 3, 4)

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