Транспонировать список списков - PullRequest
184 голосов
/ 25 июня 2011

Давайте возьмем:

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

Очень ценится

Ответы [ 10 ]

254 голосов
/ 25 июня 2011

Как насчет

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

Для пользователей Python 3.x можно использовать

list(map(list, zip(*l)))
53 голосов
/ 25 июня 2011

Один из способов сделать это с помощью транспонирования 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]]
44 голосов
/ 25 июня 2011

Эквивалентно решению Йены:

>>> 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]]
23 голосов
/ 25 июня 2011

просто для удовольствия, допустимые прямоугольники и предполагая, что 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]]
17 голосов
/ 30 января 2016

Все эти методы работают в 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(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's .

метод 2

>>> [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(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 transpose и проходит через рваные списки.Но None не должно быть значением заполнения.(Нет, значение None, переданное внутренней карте (), не является значением заполнения. Это означает, что нет функции для передачи строк.)

2 голосов
/ 05 сентября 2017

Три варианта на выбор:

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]
1 голос
/ 30 апреля 2015

Возможно, не самое элегантное решение, но вот решение, использующее вложенные циклы 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 голосов
/ 15 апреля 2018
import numpy as np
r = list(map(list, np.transpose(l)))
0 голосов
/ 07 августа 2016

Вот решение для транспонирования списка списков, который не обязательно квадратный:

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])
0 голосов
/ 16 июля 2015
    #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
...