转置列表清单

tit*_*tus 200 python transpose list

让我们来:

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Run Code Online (Sandbox Code Playgroud)

我正在寻找的结果是

r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Run Code Online (Sandbox Code Playgroud)

并不是

r = [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Run Code Online (Sandbox Code Playgroud)

非常感激

jen*_*ena 283

怎么样

map(list, zip(*l))
--> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Run Code Online (Sandbox Code Playgroud)

对于python 3.x用户可以使用

list(map(list, zip(*l)))
Run Code Online (Sandbox Code Playgroud)

  • 要注意:如果`l`的大小不均匀(例如,某些行比其他行短),`zip`将_not_补偿它,而是从输出中删除行.所以`l = [[1,2],[3,4],[5]]`给你`[[1,3,5]]`. (60认同)
  • `itertools`函数`zip_longest()`适用于不均匀的列表.见[DOCS](https://docs.python.org/3.4/library/itertools.html#itertools.zip_longest) (25认同)
  • 答案中的解释会很好:) (10认同)
  • 我认为即使`list(zip(* l))`在Python 3中也能正常工作。 (3认同)
  • @Stefano它的工作原理(和Python 2中的`zip(*l)`一样),但你得到的是元组列表,而不是列表列表.当然,`list(list(it))`总是与`list(it)`相同. (3认同)
  • @JimJam 这可行,但不满足要求。OP想要一个列表的列表,而不是元组的列表。因此地图(列表,...):) (2认同)

Sig*_*gyF 55

一种方法是使用NumPy转置.对于列表,a:

>>> import numpy as np
>>> np.array(a).T.tolist()
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Run Code Online (Sandbox Code Playgroud)

或另一个没有拉链的:

>>> map(list,map(None,*a))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Run Code Online (Sandbox Code Playgroud)

  • `map(None,...)`似乎对Py3不起作用.生成生成器但是`next()`立即引发错误:`TypeError:'NoneType'对象不可调用`. (13认同)
  • 爱你的第二个 - 我没有意识到`map`可以做到这一点.这里有一个细微的改进,不需要2次调用,但是:`map(lambda*a:list(a),*l)` (8认同)
  • 这不是一个更好的答案,因为它照顾不均匀的列表? (7认同)

ins*_*get 48

与耶拿的解决方案完全相同:

>>> l=[[1,2,3],[4,5,6],[7,8,9]]
>>> [list(i) for i in zip(*l)]
... [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Run Code Online (Sandbox Code Playgroud)

  • 由于列表理解现在比`map()`更受欢迎,因此这个解决方案是Python精神中最多的解决方案...... (7认同)

mat*_*hew 24

只是为了有趣,有效的矩形并假设m [0]存在

>>> m = [[1,2,3],[4,5,6],[7,8,9]]
>>> [[row[i] for row in m] for i in range(len(m[0]))]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Run Code Online (Sandbox Code Playgroud)

  • 仍然不太正确 - 只有在尺寸为正方形时才会发生这种情况!它应该是:`[[j [i]为j in l] for i in range(len(l [0]))]`.当然,你必须确保列表`l`不为空. (9认同)
  • 是的,需要几个轮胎才能做到这一点.好吧,很多尝试. (3认同)
  • @hobs这是badp的例子,回应jena.但是,我不确定这对我有意义.IMO,转置意味着矩形矩阵 - 当表示为列表列表时,这意味着所有内部列表必须具有相同的长度.你想要什么结果作为这个例子的"转置"? (3认同)

Bob*_*ein 21

这些方法都适用于Python 2或3.它们适用于"粗糙"的矩形2D列表.也就是说,内部列表不需要具有相同的长度.

设置

import itertools
import six

list_list = [[1,2,3], [4,5,6, 6.1, 6.2, 6.3], [7,8,9]]
Run Code Online (Sandbox Code Playgroud)

方法1

>>> list(map(list, six.moves.zip_longest(*list_list, fillvalue='-')))
[[1, 4, 7], [2, 5, 8], [3, 6, 9], ['-', 6.1, '-'], ['-', 6.2, '-'], ['-', 6.3, '-']]
Run Code Online (Sandbox Code Playgroud)

map()

默认的填充值是itertools.izip_longest().感谢@ jena的回答,itertools.zip_longest()将内部元组更改为列表.在这里,它将迭代器转换为列表.感谢@ Oregano和@ badp的评论.

方法2

>>> [list(row) for row in six.moves.zip_longest(*list_list, fillvalue='-')]
[[1, 4, 7], [2, 5, 8], [3, 6, 9], ['-', 6.1, '-'], ['-', 6.2, '-'], ['-', 6.3, '-']]
Run Code Online (Sandbox Code Playgroud)

@ inspectorG4dget替代.

方法3

>>> map(list, map(None, *list_list))
[[1, 4, 7], [2, 5, 8], [3, 6, 9], [None, 6.1, None], [None, 6.2, None], [None, 6.3, None]]
Run Code Online (Sandbox Code Playgroud)

这个非常紧凑的@SiggyF第二种选择适用于参差不齐的 2D列表,不像他的第一个使用numpy转置并通过不规则列表的代码.但无必须是填充值.(不,传递给内部map()的None不是填充值.这意味着没有传递行的功能.)


jas*_*ard 8

三个选项可供选择:

1. 带邮编的地图

solution1 = map(list, zip(*l))
Run Code Online (Sandbox Code Playgroud)

2. 列表理解

solution2 = [list(i) for i in zip(*l)]
Run Code Online (Sandbox Code Playgroud)

3. For 循环追加

solution3 = []
for i in zip(*l):
    solution3.append((list(i)))
Run Code Online (Sandbox Code Playgroud)

并查看结果:

print(*solution1)
print(*solution2)
print(*solution3)

# [1, 4, 7], [2, 5, 8], [3, 6, 9]
Run Code Online (Sandbox Code Playgroud)