DocsHub
PythonIntermediate

Rotate Array

Learn how to rotate a list left or right by K positions in Python.

Rotate Array

Problem

Rotating an array means shifting all elements by K positions. Elements that fall off one end come back on the other end.

Right rotation — elements move to the right, the last element wraps to the front:

Input:  [1, 2, 3, 4, 5], k=2
Output: [4, 5, 1, 2, 3]

Left rotation — elements move to the left, the first element wraps to the back:

Input:  [1, 2, 3, 4, 5], k=2
Output: [3, 4, 5, 1, 2]

More examples:

Right rotate [1, 2, 3, 4, 5] by 1 → [5, 1, 2, 3, 4]
Right rotate [1, 2, 3, 4, 5] by 5 → [1, 2, 3, 4, 5]  (full circle)
Right rotate [1, 2, 3, 4, 5] by 7 → [4, 5, 1, 2, 3]  (same as k=2)

Left rotate  [1, 2, 3, 4, 5] by 1 → [2, 3, 4, 5, 1]
Left rotate  [1, 2, 3, 4, 5] by 2 → [3, 4, 5, 1, 2]

Logic

Right rotation by k:

  • The last k elements move to the front
  • The remaining elements shift right

Key insight:

  • k = k % len(array) — rotating by the full length brings you back to the start
  • So k=7 on a list of 5 is the same as k=2

Visual:

Original:      [1, 2, 3, 4, 5]   k=2
               [─────────][───]
               first part  last k

Right rotated: [4, 5, 1, 2, 3]
               last k + first part

Flow

Yes No Right Left Start k = k mod lengthhandle full rotations k == 0? Return original — no change Direction? Take last k elementsput them at front Take first k elementsput them at back Return rotated array

Solution 1 — using slicing

The cleanest Python approach. Split the list at the right position and rejoin.

def rotate_right(arr, k):
    if not arr:
        return arr

    n = len(arr)
    k = k % n   # handle k larger than array length

    if k == 0:
        return arr[:]   # no rotation needed

    # last k elements go to the front
    # first (n-k) elements go to the back
    return arr[-k:] + arr[:-k]


def rotate_left(arr, k):
    if not arr:
        return arr

    n = len(arr)
    k = k % n

    if k == 0:
        return arr[:]

    # first k elements go to the back
    # remaining elements go to the front
    return arr[k:] + arr[:k]


nums = [1, 2, 3, 4, 5]

print(rotate_right(nums, 1))   # [5, 1, 2, 3, 4]
print(rotate_right(nums, 2))   # [4, 5, 1, 2, 3]
print(rotate_right(nums, 5))   # [1, 2, 3, 4, 5]
print(rotate_right(nums, 7))   # [4, 5, 1, 2, 3]

print(rotate_left(nums, 1))    # [2, 3, 4, 5, 1]
print(rotate_left(nums, 2))    # [3, 4, 5, 1, 2]

Code Execution — Solution 1

Trace through rotate_right([1, 2, 3, 4, 5], k=2):

StepCodeResult
Inputarr = [1,2,3,4,5], k = 2
Normalize kk = 2 % 5k = 2
Last k elementsarr[-2:][4, 5]
First n-k elementsarr[:-2][1, 2, 3]
Combine[4, 5] + [1, 2, 3][4, 5, 1, 2, 3]

Trace through rotate_right([1, 2, 3, 4, 5], k=7):

StepCodeResult
Normalize kk = 7 % 5k = 2
Last k elementsarr[-2:][4, 5]
First n-k elementsarr[:-2][1, 2, 3]
Combine[4, 5] + [1, 2, 3][4, 5, 1, 2, 3]

k = 7 % 5 = 2 — rotating by 7 is the same as rotating by 2 since the array has 5 elements.

Trace through rotate_left([1, 2, 3, 4, 5], k=2):

StepCodeResult
Normalize kk = 2 % 5k = 2
First k elementsarr[:2][1, 2]
Remaining elementsarr[2:][3, 4, 5]
Combine[3, 4, 5] + [1, 2][3, 4, 5, 1, 2]

k % n is the key. If k == n, you are back to the start. If k > n, you have gone around more than once. The modulo operation reduces any k to an equivalent rotation within one full cycle.


Solution 2 — using a loop

Rotate one step at a time — repeat k times. Good for understanding what rotation actually does.

def rotate_right_one_step(arr):
    """Rotate the array right by exactly one position."""
    if len(arr) <= 1:
        return arr[:]

    # save the last element
    last = arr[-1]

    # shift everything one position to the right
    rotated = [last] + arr[:-1]

    return rotated


def rotate_right(arr, k):
    if not arr:
        return arr

    k = k % len(arr)
    result = arr[:]   # work on a copy

    for _ in range(k):
        result = rotate_right_one_step(result)

    return result


def rotate_left(arr, k):
    if not arr:
        return arr

    k = k % len(arr)
    result = arr[:]

    for _ in range(k):
        # save the first element
        first = result[0]
        # shift everything left
        result = result[1:] + [first]

    return result


nums = [1, 2, 3, 4, 5]

print(rotate_right(nums, 2))   # [4, 5, 1, 2, 3]
print(rotate_left(nums, 2))    # [3, 4, 5, 1, 2]

Code Execution — Solution 2

Trace through rotate_right([1, 2, 3, 4, 5], k=2):

Step 1 — first rotation:

ActionResult
last = arr[-1]last = 5
[last] + arr[:-1][5] + [1,2,3,4] = [5,1,2,3,4]

Step 2 — second rotation:

ActionResult
last = arr[-1]last = 4
[last] + arr[:-1][4] + [5,1,2,3] = [4,5,1,2,3]

Final: [4, 5, 1, 2, 3]


Solution 3 — using collections.deque

A deque (double-ended queue) has a built-in rotate() method — positive values rotate right, negative values rotate left.

from collections import deque

def rotate(arr, k):
    """
    Positive k = right rotation
    Negative k = left rotation
    """
    if not arr:
        return arr

    d = deque(arr)
    d.rotate(k)      # positive = right, negative = left
    return list(d)


nums = [1, 2, 3, 4, 5]

print(rotate(nums, 2))    # [4, 5, 1, 2, 3]  right by 2
print(rotate(nums, -2))   # [3, 4, 5, 1, 2]  left by 2
print(rotate(nums, 1))    # [5, 1, 2, 3, 4]  right by 1
print(rotate(nums, -1))   # [2, 3, 4, 5, 1]  left by 1

Code Execution — Solution 3

deque.rotate(k):

  • Positive k → right rotation → last element goes to front
  • Negative k → left rotation → first element goes to back

Trace through rotate([1, 2, 3, 4, 5], k=2):

deque([1, 2, 3, 4, 5]).rotate(2):

rotation 1: deque([5, 1, 2, 3, 4]) — last element 5 goes to front rotation 2: deque([4, 5, 1, 2, 3]) — last element 4 goes to front

list(deque([4, 5, 1, 2, 3])) = [4, 5, 1, 2, 3]


Solution 4 — in-place using reversal

A clever algorithm — reverse the entire array, then reverse the two parts separately. No extra memory needed.

def reverse(arr, start, end):
    """Reverse arr from index start to end in place."""
    while start < end:
        arr[start], arr[end] = arr[end], arr[start]
        start += 1
        end -= 1

def rotate_right_inplace(arr, k):
    n = len(arr)
    k = k % n

    if k == 0:
        return

    # step 1 — reverse the entire array
    reverse(arr, 0, n - 1)

    # step 2 — reverse the first k elements
    reverse(arr, 0, k - 1)

    # step 3 — reverse the remaining elements
    reverse(arr, k, n - 1)


nums = [1, 2, 3, 4, 5]
rotate_right_inplace(nums, 2)
print(nums)   # [4, 5, 1, 2, 3]

nums = [1, 2, 3, 4, 5]
rotate_right_inplace(nums, 1)
print(nums)   # [5, 1, 2, 3, 4]

Code Execution — Solution 4

Trace through rotate_right_inplace([1, 2, 3, 4, 5], k=2):

Step 1 — reverse entire array:

[1, 2, 3, 4, 5] → [5, 4, 3, 2, 1]

Step 2 — reverse first k=2 elements:

[5, 4, 3, 2, 1] → [4, 5, 3, 2, 1]
   ↑↑ reversed

Step 3 — reverse remaining elements (index 2 to end):

[4, 5, 3, 2, 1] → [4, 5, 1, 2, 3]
         ↑↑↑ reversed

Result: [4, 5, 1, 2, 3]

The reversal algorithm is the most efficient approach — it rotates in-place using O(1) extra memory. It only swaps elements without creating any new lists. This is the approach used in competitive programming and technical interviews.


Bonus — rotate a 2D matrix

Rotate a square matrix 90 degrees clockwise.

def rotate_matrix_90(matrix):
    n = len(matrix)

    # step 1 — transpose (swap rows and columns)
    for i in range(n):
        for j in range(i + 1, n):
            matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

    # step 2 — reverse each row
    for row in matrix:
        row.reverse()

    return matrix


matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

rotate_matrix_90(matrix)

for row in matrix:
    print(row)

Output:

[7, 4, 1]
[8, 5, 2]
[9, 6, 3]

Which solution to use?

SolutionHowBest when
Solution 1SlicingCleanest, most Pythonic
Solution 2Loop step by stepUnderstanding the concept
Solution 3deque.rotate()Simple one-liner
Solution 4Reversal algorithmIn-place, no extra memory

Output

[5, 1, 2, 3, 4]
[4, 5, 1, 2, 3]
[1, 2, 3, 4, 5]
[4, 5, 1, 2, 3]

[2, 3, 4, 5, 1]
[3, 4, 5, 1, 2]

On this page