将一个元组列表拆分成两个列表

7
我有一个元组列表,如下所示:[(12,1),(123,4),(33,4)],我想把它变成[12,123,33][1,4,4]。请问我该怎么做?
提前感谢您的帮助。
3个回答

21

您可以使用zip()函数:

zipped = [(12, 1), (123, 4), (33, 4)]
>>> b, c = zip(*zipped)
>>> b 
(12, 123, 33)
>>> c
(1, 4, 4)

或者您可以使用列表推导式来实现类似的效果:

>>> b, c = [e[0] for e in zipped], [e[1] for e in zipped]
>>> b
[12, 123, 33]
>>> c
[1, 4, 4]

不同之处在于,一个给你一个元组列表(zip),另一个给你两个列表的元组(使用两个列表推导式)。

在这种情况下,zip 可能是更Pythonic并且速度更快的方法。


2
不仅该答案可行,而且还是如何用Python思考的好例子。 - austin
1
第一个例子是一个可怕的想法 - 它只适用于序列,而不是任意可迭代对象,它更慢,并且重新发明了内置函数的轮子,对于一个更有限的情况。在这里应该考虑的唯一答案是 zip()。把最糟糕的方法放在第一位最多是误导性的。 - Gareth Latty
@Lattyware 你说得对,我把例子搞反了,更符合Python风格的应该放在前面。不过我认为列表推导式也有它们的用途,不应该被忽视。 - pyrrrat
我去掉了-1,但实际上在这里没有任何使用场景适合列表推导式作为更好的解决方案。如果你真的需要一个列表的列表(这几乎不太可能),NPE的答案是最佳选择。 - Gareth Latty

9

这是使用zip()的完美案例:

In [41]: l = [(12,1), (123,4), (33,4)]

In [42]: a, b = map(list, zip(*l))

In [43]: a
Out[43]: [12, 123, 33]

In [44]: b
Out[44]: [1, 4, 4]

如果您不介意 ab 是元组而不是列表,那么您可以删除 map(list, ...) 并保留 a, b = zip(*l)

我会建议只使用zip(*l),然后,在极少需要列表而不是元组的情况下,使用map()来创建它们。99%的时间,你不需要这样做。 - Gareth Latty
l 可以是任何可迭代对象吗? - Inyoung Kim 김인영

1
这是我的尝试。
first_list = []
second_list = []

for tup in list_of_tuples:
    first_list.append(ls[0])
    second_list.append(ls[1])

根据我的实验,这个解决方案甚至比zip更快:https://dev59.com/iWsz5IYBdhLWcg3wLEm8#47148258 - franklsf95

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