如何解压缩嵌套列表中的元组?

时间:2014-12-09 03:29:01

标签: python list tuples

我在打开二维元组列表时遇到问题(或者更确切地说,我正在寻找更优雅的解决方案)。

列表如下所示:

a = [ [(2, 3, 5), (3, 4, 6), (4, 5, 7), (1, 1, 1), (1, 2, 3)],
      [(4, 9, 2), (8, 8, 0), (3, 5, 1), (2, 6, 8), (2, 4, 8)],
      [(8, 7, 5), (2, 5, 1), (9, 2, 2), (4, 5, 1), (0, 1, 9)], ...]

我想解开元组以获得3个相同形式的嵌套列表,即:

a_r = [ [2, 3, 4, 1, 1] , [4, 8, 3, 2, 2] , [8, 2, 9, 4, 0] , ...]
a_g = [ [3, 4, 5, 1, 2] , [9, 8, 5, 6, 4] , [7, 5, 2, 5, 1] , ...]

等等。这是我的代码:

a_r = []
a_g = []
a_b = []

for i in xrange(len(a)):
    r0=[]
    g0=[]
    b0=[]
    for j in range(5):
        r0.append(a[i][j][0])
        g0.append(a[i][j][1])
        b0.append(a[i][j][2])
    a_r.append(r0)
    a_g.append(g0)
    a_b.append(b0)

我确信有更有效的方法可以做到这一点(我刚刚开始学习Python)。 This question类似,但我无法遵循函数式编程。

谢谢!

3 个答案:

答案 0 :(得分:4)

我认为你是在追求这样的事情:

a = [ [(2, 3, 5), (3, 4, 6), (4, 5, 7), (1, 1, 1), (1, 2, 3)],
      [(4, 9, 2), (8, 8, 0), (3, 5, 1), (2, 6, 8), (2, 4, 8)],
      [(8, 7, 5), (2, 5, 1), (9, 2, 2), (4, 5, 1), (0, 1, 9)]]

for row in a:
    print(list(zip(*row)))

给出了:

[(2, 3, 4, 1, 1), (3, 4, 5, 1, 2), (5, 6, 7, 1, 3)]
[(4, 8, 3, 2, 2), (9, 8, 5, 6, 4), (2, 0, 1, 8, 8)]
[(8, 2, 9, 4, 0), (7, 5, 2, 5, 1), (5, 1, 2, 1, 9)]

生成的元组与示例中的元组相同,但顺序不同。我不明白你是如何订购它们的。如果你能澄清一下,我可能会修改这个例子。

希望这有帮助。

答案 1 :(得分:3)

>>> a = [ [(2, 3, 5), (3, 4, 6), (4, 5, 7), (1, 1, 1), (1, 2, 3)],
...       [(4, 9, 2), (8, 8, 0), (3, 5, 1), (2, 6, 8), (2, 4, 8)],
...       [(8, 7, 5), (2, 5, 1), (9, 2, 2), (4, 5, 1), (0, 1, 9)]]
>>> zip(*(zip(*x) for x in a))
[((2, 3, 4, 1, 1), (4, 8, 3, 2, 2), (8, 2, 9, 4, 0)), ((3, 4, 5, 1, 2), (9, 8, 5, 6, 4), (7, 5, 2, 5, 1)), ((5, 6, 7, 1, 3), (2, 0, 1, 8, 8), (5, 1, 2, 1, 9))]

>>> for row in _:
...     print row
... 
((2, 3, 4, 1, 1), (4, 8, 3, 2, 2), (8, 2, 9, 4, 0))
((3, 4, 5, 1, 2), (9, 8, 5, 6, 4), (7, 5, 2, 5, 1))
((5, 6, 7, 1, 3), (2, 0, 1, 8, 8), (5, 1, 2, 1, 9))

如果必须是列表

>>> map(list, zip(*(map(list, zip(*x)) for x in a)))
[[[2, 3, 4, 1, 1], [4, 8, 3, 2, 2], [8, 2, 9, 4, 0]], [[3, 4, 5, 1, 2], [9, 8, 5, 6, 4], [7, 5, 2, 5, 1]], [[5, 6, 7, 1, 3], [2, 0, 1, 8, 8], [5, 1, 2, 1, 9]]]
>>> for row in _:
...     print row
... 
[[2, 3, 4, 1, 1], [4, 8, 3, 2, 2], [8, 2, 9, 4, 0]]
[[3, 4, 5, 1, 2], [9, 8, 5, 6, 4], [7, 5, 2, 5, 1]]
[[5, 6, 7, 1, 3], [2, 0, 1, 8, 8], [5, 1, 2, 1, 9]]

答案 2 :(得分:0)

元组是不可变的(意味着你无法改变它们),因此你将不得不通过每个元素来提取它们。这基本上就是您链接到的函数式编程示例正在以非常pythonic的列表理解方式进行的。

为了帮助你自己,正如shirdharama所说,再看看这个例子并知道fmap_lol实际上意味着“函数映射 - 列表列表”,fmap_list表示“函数映射 - 列表”,fmap_el表示“函数映射” - 元素“。因此,split_nt调用fmap_lol,它将您的输入拆分为列表列表(元组),调用fmap_list,它接受每个列表并调用fmap_el,它返回链返回元素。

该示例只是一种遍历元组以提取每个元素并将它们放在您希望的位置的方法。它的功能是因为它们是函数调用,而不是后来被遗忘的gobbligook的一行。

如果您不熟悉列表推导,lamda(或匿名函数)或示例中的任何其他内容,我建议您花一些时间阅读python文档并查看每个文档。