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

説明:

何が起こっているのかを理解するために知っておくべきことが 2 つあります。

  1. zipの署名:zip(*iterables)これはzip、それぞれが反復可能でなければならない任意の数の引数を期待することを意味します。例zip([1, 2], [3, 4], [5, 6])
  2. アンパックされた引数リスト: 一連の引数を指定すると、 の各要素が の個別の位置引数argsf(*args)なるように が呼び出されます。fargsf
  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

それを行う 1 つの方法は、NumPy transposeを使用することです。リストの場合:

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

またはzipなしの別のもの:

>>> 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()になる

デフォルトの fillvalue は ですNone@jena's answerのおかげでmap()、内部タプルをリストに変更しています。ここでは、イテレータをリストに変換しています。@Oregano と @badp のコメントに感謝します。

Python 3 では、結果をパススルーしてlist()、方法 2 と同じ 2D リストを取得します。


方法 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 の 2 番目の代替案は、numpy を使用して不規則なリストを転置および通過する最初のコードとは異なり、不規則な 2D リストで機能します。ただし、フィル値は 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 に答える
0

正方行列のもう 1 つの方法。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 に答える