这是一种适用于非方阵的相当有效的方法:
DIRS = NONE, UP, DOWN, LEFT, RIGHT = 'unshifted', 'up', 'down', 'left', 'right'
def shift(matrix, direction, dist):
""" Shift a 2D matrix in-place the given distance of rows or columns in the
specified (NONE, UP, DOWN, LEFT, RIGHT) direction and return it.
"""
if dist and direction in (UP, DOWN, LEFT, RIGHT):
n = 0
if direction in (UP, DOWN):
n = (dist % len(matrix) if direction == UP else -(dist % len(matrix)))
elif direction in (LEFT, RIGHT):
n = (dist % len(matrix[0]) if direction == LEFT else -(dist % len(matrix[0])))
matrix[:] = list(zip(*matrix)) # Transpose rows and columns for shifting.
h = matrix[:n]
del matrix[:n]
matrix.extend(h)
if direction in (LEFT, RIGHT):
matrix[:] = map(list, zip(*matrix)) # Undo previous transposition.
return matrix
if __name__ == '__main__':
# Some non-square test matrices.
matrix1 = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]
matrix2 = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]]
def shift_and_print(matrix, direction, dist):
GAP = 2 # Plus one for a ":" character.
indent = max(map(len, DIRS)) + GAP
print(direction
+ ': ' + (indent-2-len(direction))*' '
+ ('\n'+indent*' ').join(map(str, shift(matrix, direction, dist)))
+ '\n')
for matrix in matrix1, matrix2:
for direction in DIRS:
shift_and_print(matrix, direction, 1) # Printed results are cumulative.
输出(请注意,结果是累积的,因为操作是就地执行的,并且移位应用于上一次调用的结果):
no shift: [1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10, 11, 12]
up: [4, 5, 6]
[7, 8, 9]
[10, 11, 12]
[1, 2, 3]
down: [1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10, 11, 12]
left: [2, 3, 1]
[5, 6, 4]
[8, 9, 7]
[11, 12, 10]
right: [1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10, 11, 12]
no shift: [1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
up: [5, 6, 7, 8]
[9, 10, 11, 12]
[1, 2, 3, 4]
down: [1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
left: [2, 3, 4, 1]
[6, 7, 8, 5]
[10, 11, 12, 9]
right: [1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]