목록의 전치


241

해 보자:

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

매우 감사

답변:


336

어때요?

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

파이썬 3.x의 경우 사용자는

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

설명:

무슨 일이 일어나고 있는지 이해하기 위해 알아야 할 두 가지가 있습니다.

  1. zip 의 서명 : zip(*iterables)이것은 zip각각 반복 가능 해야하는 임의의 수의 인수를 예상 한다는 것을 의미 합니다. 예 zip([1, 2], [3, 4], [5, 6]).
  2. 압축을 푼 인수 목록 : 인수의 순서 감안할는 args, f(*args)호출 f의 각 요소가되도록 args별도의 위치 인수입니다 f.

질문의 입력에 다시오고 l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], zip(*l)에 해당 될 것이다 zip([1, 2, 3], [4, 5, 6], [7, 8, 9]). 나머지는 결과가 튜플 목록 대신 목록 목록인지 확인하는 것입니다.


67
주의 : 경우에 l균일하게 (예를 들어, 일부 행이 다른 사람보다 짧은) 크기되지, zip않습니다 하지 그것을 보상 대신 출력에서 행을 멀리 들어온다. 그래서 l=[[1,2],[3,4],[5]]당신에게 제공합니다 [[1,3,5]].
badp

29
itertools기능 zip_longest()은 고르지 않은 목록에서 작동합니다.
오레가노

13
이에 대한 설명은 좋을 것입니다 :)
Boris Churzin

7
list(zip(*l))파이썬 3 에서도 제대로 작동 한다고 생각 합니다.
Stefano

3
@Stefano 그것은 작동 zip(*l)하지만 (Python 2에서 와 마찬가지로 ) 목록 목록이 아닌 튜플 목록을 얻습니다. 물론 list(list(it))항상와 같습니다 list(it).
Alex Shpilkin

62

이를 수행하는 한 가지 방법은 NumPy 조옮김입니다. 목록의 경우 :

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

8
당신의 두 번째 것을 사랑하십시오-나는 그것을 map할 수 있다는 것을 몰랐습니다 . 여기에 2 번의 전화가 필요없는 약간의 개선이 있습니다.map(lambda *a: list(a), *l)
Lee D

7
고르지 않은 목록을 처리하기 때문에 이것이 더 나은 대답이어야합니까?
레온

15
map(None, ...)Py3에서는 작동하지 않는 것 같습니다. 생성기가 생성되었지만 next()즉시 오류가 발생합니다 TypeError: 'NoneType' object is not callable..
Mad Physicist

57

예나의 솔루션과 동일합니다.

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

12
리스트 이해가 선호되기 때문에 map(),이 솔루션은 파이썬 정신에서 가장 큰 솔루션입니다.
perror

26

재미 있고 유효한 사각형을 위해 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]]

이것은 내가 찾고 있었고 내 머리를 얻을 수 없었습니다. 여전히 @jena의 솔루션은 정말 짧습니다
titus

3
네, 이걸 제대로 이해하려면 타이어가 약간 필요했습니다. 많은 시도가 있습니다.
matchew

9
여전히 옳지 않습니다-치수가 정사각형 일 때만 작동합니다! 이어야합니다 [[j[i] for j in l] for i in range(len(l[0]))]. 물론 목록 l이 비어 있지 않은지 확인해야합니다 .
Lee D

@LeeD는 jena의 예제에서 여전히 작동하지 않습니다. l = [[1,2], [3,4], [5]]
hobs

3
@hobs 그것은 jena에 응답하는 badp의 예였습니다. 그러나 나는 그것이 의미가 있는지 확실하지 않습니다. IMO에서 조옮김은 직사각형 행렬을 의미합니다. 목록의 목록으로 표시 될 때 모든 내부 목록의 길이가 같아야합니다. 이 예제의 "조옮김"으로 어떤 결과를 원하십니까?
Lee D

22

방법 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입니다. 예나의 @ 덕분에 대답 , 어디 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의 두 번째 대안 은 numpy를 사용하여 거친 목록을 바꾸고 통과하는 첫 번째 코드와 달리 거친 2D 목록과 함께 작동합니다. 그러나 없음은 채우기 값이어야합니다. (아니요, 내부 map ()에 전달 된 None은 채우기 값이 아닙니다. 이는 각 열을 처리하는 함수가 없음을 의미합니다. 열은 외부 맵 ()으로 전달되어 튜플에서 목록으로 변환됩니다.

파이썬 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에서 비정형 열이되지 않으며 잘립니다. 부후 진행.


7

선택할 수있는 세 가지 옵션 :

1. Zip으로지도

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

2. 목록 이해

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

3. 루프 추가

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]

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


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

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

-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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.