让我们来:

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

我想要的结果是

r = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

而不是

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

当前回答

import numpy as np
r = list(map(list, np.transpose(l)))

其他回答

方阵的另一种方法。不使用numpy和itertools,使用(有效的)就地元素交换。

def transpose(m):
    for i in range(1, len(m)):
        for j in range(i):
            m[i][j], m[j][i] = m[j][i], m[i][j]

Python 3:

# short circuits at shortest nested list if table is jagged:
list(map(list, zip(*l)))

# discards no data if jagged and fills short nested lists with None
list(map(list, itertools.zip_longest(*l, fillvalue=None)))

Python 2:

map(list, zip(*l))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

解释:

要了解发生了什么,我们需要知道两件事:

The signature of zip: zip(*iterables) This means zip expects an arbitrary number of arguments each of which must be iterable. E.g. zip([1, 2], [3, 4], [5, 6]). Unpacked argument lists: Given a sequence of arguments args, f(*args) will call f such that each element in args is a separate positional argument of f. itertools.zip_longest does not discard any data if the number of elements of the nested lists are not the same (homogenous), and instead fills in the shorter nested lists then zips them up.

回到问题l =[[1,2,3],[4,5,6],[7,8,9]]的输入,zip(*l)将等价于zip([1,2,3],[4,5,6],[7,8,9])。剩下的就是确保结果是列表的列表,而不是元组的列表。

也许不是最优雅的解决方案,但这里有一个使用嵌套while循环的解决方案:

def transpose(lst):
    newlist = []
    i = 0
    while i < len(lst):
        j = 0
        colvec = []
        while j < len(lst):
            colvec.append(lst[j][i])
            j = j + 1
        newlist.append(colvec)
        i = i + 1
    return newlist

一种方法是用NumPy转置。如需列出清单,请填写:

>>> import numpy as np
>>> np.array(l).T.tolist()
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

或者另一个没有zip (python < 3)的:

>>> map(list, map(None, *l))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

或者对于python >= 3:

>>> list(map(lambda *x: list(x), *l))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
import numpy as np
r = list(map(list, np.transpose(l)))