2013-11-29 3 views
3

У меня есть 2d список вроде этого:Как я инвертировать 2d список в Python

1 2 3 

    4 5 6 

, и я хочу сделать это:

1 4 

    2 5 

    3 6 

Я пытался сделать цикл и переключить каждое значение, но я продолжаю получать индекс из связанной ошибки. Вот что у меня есть:

for i in results: 
    for j in range(numCenturies): 
     rotated[i][j] = results [j][i] 
+1

Это называется «транспонирование», а не «инвертирование». Инвертирование списка просто означает перевернуть его вверх дном, не вращая его на 90 градусов. – abarnert

ответ

9

из питона документации на zip функции:

Эта функция возвращает список кортежей, где я-й кортеж содержит I-й элемент из каждого аргумента последовательностей или итераций. Возвращаемый список усекается по длине с длиной кратчайшей последовательности аргументов. Когда есть несколько аргументов, которые имеют одинаковую длину, zip() похож на map() с начальным аргументом None. С одним аргументом последовательности он возвращает список из 1-кортежей. Без аргументов он возвращает пустой список.

Пример:

zip([1, 2, 3], [4, 5, 6]) # returns [(1, 4), (2, 5), (3, 6)] 

Если вам нужен результат как список списков, а не список кортежей, вы можете использовать список понимание:

[list(x) for x in zip([1, 2, 3], [4, 5, 6], [7, 8, 9])] # returns [[1, 4, 7], [2, 5, 8], [3, 6, 9]] 

Если все ваши переменные хранятся в одном списке 2d, и вы хотите, чтобы он передал его в zip-функцию, вы можете использовать следующее (я назову его звездным обозначением, потому что я не могу вспомнить правильный английский термин для него):

results = [[1, 2, 3], [4, 5, 6]] 
zip(*results) # returns [(1, 4), (2, 5), (3, 6)] 
+0

Но что, если есть более двух строк? –

+0

@AswinMurugesh работает с любым количеством строк: zip ([1,2,3], [4,5,6], [7,8,9]) возвращает [(1, 4, 7), (2 , 5, 8), (3, 6, 9)] – aga

+0

Есть ли способ, которым я мог бы использовать это, если бы все было сохранено в переменной? Например, если у меня был список 2d, называемый результатами, и я не был уверен, насколько он значителен, как передать его функции zip? –

1

zip это правильный способ сделать это, как показано на агу.

Но если вы хотите знать, почему ваш исходный код не работает:

for i in results: 
    for j in range(numCenturies): 
     rotated[i][j] = results [j][i] 

Есть два очевидных проблем здесь, и, вероятно, две другие. (Так как вы не показали нам достаточно кода или данных, чтобы убедиться, что я не могу гарантировать, два вероятных из них.)

Предположительно results выглядит примерно так:

results = [[1, 2, 3], [4, 5, 6]] 

Когда вы делаете for i in results, это означает, что i будет каждый элемент в результатах, то есть он будет [1, 2, 3], а затем [4, 5, 6]. Вы не можете использовать список в качестве индекса в списке, так что это гарантированно даст вам TypeError: list indices must be integers, not list.

Чтобы это исправить, вам нужно:

for i in range(len(results)): 

... или ...

for i, row in enumerate(results): 

Далее results[j][i] гарантированно поднять IndexError: list index out of range, потому что i есть каждый ряд номер, но вы пытаетесь использовать его как столбец . Если вы итерация строк и столбцов results, вы хотите:

rotated[j][i] = results[i][j] 

Далее, если вы предварительно не заполнены rotated с 3 списков, каждый из которых был предварительно заполненные 2 объектов что-то вроде, вы получите IndexError: list assignment index out of range.

Чтобы это исправить, необходимо предварительно заполнить rotated, что-то вроде этого:

rotated = [[None for j in range(2)] for i in range(3)] 

... или ...

rotated = [[None, None], [None, None], [None, None]] 

Наконец, я буду держать пари numCenturies 3, в этом случае вы получите еще IndexError: list index out of range, как только j достигнет 2. Простейшая вещь здесь - просто использовать длину строки; таким образом, нет возможности по ошибке.

Собираем все вместе:

rotated = [[None for j in range(2)] for i in range(3)] 
for i, row in enumerate(results): 
    for j, value in enumerate(row): 
     rotated[j][i] = value 

Но в целом, Python дает более простые способы сделать вещи, чем до создания массивов и циклов по индексам, чтобы заполнить значения. Вы можете использовать append -или, лучше, понимание списка. Или, что еще лучше, найдите способ более высокого уровня для написания вашего использования, например, один звонок до zip.

Смежные вопросы