programing

목록의 목록을 바꿉니다.

newsource 2022. 11. 17. 21:17

목록의 목록을 바꿉니다.

예를 들어 다음과 같습니다.

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

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

설명:

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

  1. zip의 시그니처:zip(*iterables)즉,zip는 각각 반복 가능해야 하는 임의의 수의 인수를 요구합니다.예.zip([1, 2], [3, 4], [5, 6]).
  2. Unpacked 인수 목록: 일련의 인수 지정args,f(*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])나머지는 결과가 튜플 목록이 아닌 목록인지 확인하는 것입니다.

Jena의 솔루션과 동등:

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

가지 방법은 NumPy 전치입니다.리스트의 경우 a:

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

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

방법 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와 동일한 2D 목록을 얻습니다.


method 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()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 리스트에서 작동합니다.그러나 None은 채우기 값이어야 합니다.(아니, 내부 map()에 전달된 None은 채우기 값이 아닙니다.즉, 각 열을 처리하는 함수가 없습니다.컬럼은 외부 map()으로 전달되어 tuples에서 목록으로 변환됩니다.)

Python 3 어디선가 이 모든 남용에 대한 참는 것을 중단했습니다.첫 번째 파라미터는 None일 수 없으며, 누더기 반복기는 가장 짧게 잘립니다.이것은 내부 맵()에만 적용되기 때문에 다른 메서드는 계속 작동합니다.


4 : 「 」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에서는 울퉁불퉁한 행이 울퉁불퉁한 컬럼이 되지 않고 잘릴 뿐입니다.부후 진행.

다음 3가지 옵션 중에서 선택할 수 있습니다.

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]
import numpy as np
r = list(map(list, np.transpose(l)))

가장 우아한 솔루션은 아닐 수도 있지만, 네스트된 while loops를 사용하는 솔루션은 다음과 같습니다.

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

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

정사각형 행렬을 위한 한 가지 방법이 더 있습니다.numpy 또는 반복 툴은 (유효한) 내부 요소 교환을 사용하지 않습니다.

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]

그냥 재미로: 만약 당신이 그것들을 모두 받아쓰기로 만들고 싶다면.

In [1]: l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
   ...: fruits = ["Apple", "Pear", "Peach",]
   ...: [dict(zip(fruits, j)) for j in [list(i) for i in zip(*l)]]
Out[1]:
[{'Apple': 1, 'Pear': 4, 'Peach': 7},
 {'Apple': 2, 'Pear': 5, 'Peach': 8},
 {'Apple': 3, 'Pear': 6, 'Peach': 9}]

여기에서는 반드시 정사각형일 필요는 없는 리스트의 리스트를 치환하기 위한 솔루션을 나타냅니다.

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

언급URL : https://stackoverflow.com/questions/6473679/transpose-list-of-lists