Пока вы просили решение «без библиотек», я бы очень рекомендовал использовать numpy
для всего, что связано с матричными манипуляциями, такими как изменение формы или транспонирование, оба из которых вам понадобятся здесь:
>>> import numpy as np
>>> to_transpose = [0.914, 0.639, 0.058, 0.760, 0.926, 0.475,
0.255, 0.671, 0.195, 0.966, 0.336, 0.841,
0.279, 0.341, 0.591, 0.638, 0.520, 0.225]
>>> np.array(to_transpose).reshape((3,3,2)).transpose(1,0,2).ravel()
array([ 0.914, 0.639, 0.255, 0.671, 0.279, 0.341,
0.058, 0.76 , 0.195, 0.966, 0.591, 0.638,
0.926, 0.475, 0.336, 0.841, 0.52 , 0.225])
Разобьем это немного:
np.array
превращает ваш список в array
... - , который вы затем
reshape
до 3x3x2
,то есть матрица кортежей 3x3 ... - , которую вы затем
transpose
поменяете местами первую (0) и вторую (1) оси и сохраните третью (2) на месте ... - и, наконец, матрица снова сглаживается с помощью
ravel
Если вы не можете использовать numpy в конце, вы все равно можете использовать это, чтобы правильно транспонировать матрицу индексов, чтобы выяснить, какой элементдолжен пойти куда-то, а затем воспроизвести это с помощью цикла над списком to_transpose
:
>>> list(np.array(list(range(w*h))).reshape((3,3,2)).transpose(1,0,2).ravel())
[0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11, 16, 17]
>>> [i%2 + (i//2 * w % (w*h)) + 2 * (i//(h*2)) for i in range(w*h)]
[0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11, 16, 17]
>>> [to_transpose[i%2 + (i//2 * w % (w*h)) + 2 * (i//(h*2))] for i in range(w*h)]
[0.914, 0.639, 0.255, 0.671, 0.279, 0.341,
0.058, 0.76, 0.195, 0.966, 0.591, 0.638,
0.926, 0.475, 0.336, 0.841, 0.52, 0.225]
Конечно, вы можете сделать то же самое с обычными циклами вместо списочных представлений и на других языках.По сути, каждое из трех слагаемых в добавлении к индексу соответствует одному из измерений матрицы, и, честно говоря, я понял это больше, угадывая, чем реально понимая, что происходит.Само собой разумеется, что numpy
решение намного чище.