317

让我们来:

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)]

非常感激

4

13 回答 13

456

蟒蛇 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)))

蟒蛇2:

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

解释:

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

  1. zip的签名:zip(*iterables)这意味着zip需要任意数量的参数,每个参数都必须是可迭代的。例如zip([1, 2], [3, 4], [5, 6])
  2. 解包参数列表:给定参数序列argsf(*args)将调用f使得其中的每个元素args都是 的单独位置参数f
  3. itertools.zip_longest如果嵌套列表的元素数量不同(同质),则不会丢弃任何数据,而是填充较短的嵌套列表,然后将它们压缩。

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

于 2011-06-24T20:59:37.240 回答
74

一种方法是使用NumPy transpose。对于一个列表,一个:

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

或者另一个没有拉链的:

>>> map(list,map(None,*a))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
于 2011-06-24T20:59:43.183 回答
71

相当于耶拿的解决方案:

>>> 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]]
于 2011-06-24T21:02:00.577 回答
29

只是为了好玩,有效的矩形并假设 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]]
于 2011-06-24T21:06:27.307 回答
24

方法 1 和 2 适用于 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]]

方法 1 — map(),zip_longest()

>>> 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, '-']]

six.moves.zip_longest()变成

默认填充值为None. 感谢@jena 的回答map()将内部元组更改为列表在哪里。在这里,它把迭代器变成了列表。感谢@Oregano 和@badp 的评论

在 Python 3 中,传递结果list()以获得与方法 2 相同的二维列表。


方法 2 — 列表理解,zip_longest()

>>> [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, '-']]

@inspectorG4dget 替代方案。


方法 3 — map()of map()在 Python 3.6 中被破坏

>>> 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]]

这个非常紧凑的@SiggyF 第二种选择适用于参差不齐的 2D 列表,不像他的第一个代码使用 numpy 转置和通过参差不齐的列表。但是 None 必须是填充值。(不,传递给内部 map() 的 None 不是填充值。这意味着没有处理每一列的函数。这些列只是传递给外部 map() ,它将它们从元组转换为列表。)

在 Python 3 的某个地方,map()不再忍受所有这些滥用:第一个参数不能为 None,并且不规则的迭代器被截断为最短。其他方法仍然有效,因为这只适用于内部 map()。


方法4——map()map()访

>>> list(map(list, map(lambda *args: args, *list_list)))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]   // Python 2.7
[[1, 4, 7], [2, 5, 8], [3, 6, 9], [None, 6.1, None], [None, 6.2, None], [None, 6.3, None]] // 3.6+

唉,在 Python 3 中,参差不齐的行不会变成参差不齐的列,它们只是被截断了。嘘,进步。

于 2016-01-30T09:52:17.910 回答
8

三个选项可供选择:

1. 带邮编的地图

solution1 = map(list, zip(*l))

2. 列表理解

solution2 = [list(i) for i in zip(*l)]

3. For循环追加

solution3 = []
for i in zip(*l):
    solution3.append((list(i)))

并查看结果:

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

# [1, 4, 7], [2, 5, 8], [3, 6, 9]
于 2017-09-05T06:14:32.483 回答
2
import numpy as np
r = list(map(list, np.transpose(l)))
于 2018-04-15T18:31:50.090 回答
0

也许不是最优雅的解决方案,但这是使用嵌套 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
于 2015-04-30T16:04:14.980 回答
0

more_itertools.unzip()易于阅读,它也适用于生成器。

import more_itertools
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
r = more_itertools.unzip(l) # a tuple of generators.
r = list(map(list, r))      # a list of lists

或等效地

import more_itertools
l = more_itertools.chunked(range(1,10), 3)
r = more_itertools.unzip(l) # a tuple of generators.
r = list(map(list, r))      # a list of lists
于 2020-05-18T12:39:11.883 回答
0
matrix = [[1,2,3],
          [1,2,3],
          [1,2,3],
          [1,2,3],
          [1,2,3],
          [1,2,3],
          [1,2,3]]
    
rows = len(matrix)
cols = len(matrix[0])

transposed = []
while len(transposed) < cols:
    transposed.append([])
    while len(transposed[-1]) < rows:
        transposed[-1].append(0)

for i in range(rows):
    for j in range(cols):
        transposed[j][i] = matrix[i][j]

for i in transposed:
    print(i)
于 2020-10-20T21:28:03.407 回答
0

方阵的另一种方法。没有 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]
于 2021-01-04T11:00:15.350 回答
-1

这是转置不一定是正方形的列表列表的解决方案:

maxCol = len(l[0])
for row in l:
    rowLength = len(row)
    if rowLength > maxCol:
        maxCol = rowLength
lTrans = []
for colIndex in range(maxCol):
    lTrans.append([])
    for row in l:
        if colIndex < len(row):
            lTrans[colIndex].append(row[colIndex])
于 2016-08-07T14:54:37.310 回答
-2
    #Import functions from library
    from numpy import size, array
    #Transpose a 2D list
    def transpose_list_2d(list_in_mat):
        list_out_mat = []
        array_in_mat = array(list_in_mat)
        array_out_mat = array_in_mat.T
        nb_lines = size(array_out_mat, 0)
        for i_line_out in range(0, nb_lines):
            array_out_line = array_out_mat[i_line_out]
            list_out_line = list(array_out_line)
            list_out_mat.append(list_out_line)
        return list_out_mat
于 2015-07-16T00:58:56.580 回答