Давай возьмем:
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)]
Очень признателен
Давай возьмем:
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)]
Очень признателен
Как насчет
map(list, zip(*l))
--> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Для Python 3.x пользователи могут использовать
list(map(list, zip(*l)))
Один из способов сделать это с транспонированием 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]]
Эквивалентно решению Йены:
>>> 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]]
только для забавных действительных прямоугольников и предполагая, что 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]]
Первые два метода работают в Python 2 или 3 и работают с "рваными" прямоangularьными 2D-списками. То есть внутренние списки не должны иметь одинаковую длину. Другие методы, ну, это сложно.
import itertools
import six
list_list = [[1,2,3], [4,5,6, 6.1, 6.2, 6.3], [7,8,9]]
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()
становится
itertools.izip_longest()
в Python 2itertools.zip_longest()
в Python 3Значением заполнения по умолчанию является None
. Благодаря @jena answer, где map()
меняет внутренние кортежи на списки. Вот он превращал итераторы в списки. Благодаря @Oregano и @badp комментариям.
В Python 3 передайте результат через list()
, чтобы получить тот же 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.
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-списками, в отличие от его первого кода, который использует транспонирование numpy и пропускает рваные списки. Но None не должно быть значением заполнения. (Нет, значение None, переданное внутренней карте(), не является значением заполнения. Это означает, что нет функции для обработки каждого столбца. Они просто передаются во внешнюю карту(), которая преобразует их из кортежей в списки.
Где-то в Python 3 map()
перестал мириться со всем этим злоупотреблением: первым параметром не может быть None, а рваные итераторы просто усекаются до самых коротких. Другие методы все еще работают, потому что это относится только к внутренней карте().
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, они просто усекаются. Бу-ху прогресс.
solution1 = map(list, zip(*l))
solution2 = [list(i) for i in zip(*l)]
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]
Может быть, не самое изящное решение, но здесь решение с использованием вложенных циклов 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
import numpy as np
r = list(map(list, np.transpose(l)))
Вот решение для переноса списка списков, который не обязательно является квадратным:
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