Python
list rotation
programming
efficient algorithms
Python tips

Efficient way to rotate a list in python

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Rotating a list means shifting its elements left or right and wrapping the overflow back around to the other side. In Python, the most efficient approach depends on whether you need a plain list result, in-place mutation, or repeated rotations.

For many everyday cases, slicing is the cleanest answer. If you rotate often, collections.deque is usually the better data structure because rotation is built in.

Use Slicing for a Simple One-Off Rotation

If you want a rotated copy of a list, slicing is compact and fast enough for most uses:

python
1def rotate_right(values, k):
2    if not values:
3        return []
4
5    k %= len(values)
6    return values[-k:] + values[:-k]
7
8
9print(rotate_right([1, 2, 3, 4, 5], 2))  # [4, 5, 1, 2, 3]

For left rotation, flip the slices:

python
1def rotate_left(values, k):
2    if not values:
3        return []
4
5    k %= len(values)
6    return values[k:] + values[:k]
7
8
9print(rotate_left([1, 2, 3, 4, 5], 2))  # [3, 4, 5, 1, 2]

This is usually the most readable solution when you only need the rotated result once and creating a new list is acceptable.

deque.rotate Is Better for Repeated Rotations

If rotation is a frequent operation, deque is the more appropriate tool:

python
1from collections import deque
2
3values = deque([1, 2, 3, 4, 5])
4values.rotate(2)
5print(list(values))  # [4, 5, 1, 2, 3]
6
7values.rotate(-1)
8print(list(values))  # [5, 1, 2, 3, 4]

This is especially useful when the collection is conceptually circular, such as:

  • round-robin scheduling
  • rotating turn order
  • cyclic buffers

If your code rotates often, converting the data model to deque is usually more efficient than repeatedly rebuilding lists with slices.

In-Place Rotation Is Trickier

If the requirement is to mutate the original list in place, slicing assignment is a practical Python solution:

python
1def rotate_right_in_place(values, k):
2    if not values:
3        return
4
5    k %= len(values)
6    values[:] = values[-k:] + values[:-k]
7
8
9data = [1, 2, 3, 4, 5]
10rotate_right_in_place(data, 2)
11print(data)  # [4, 5, 1, 2, 3]

This still creates intermediate slices, but it preserves the original list object, which can matter if other references point to it.

That is often the right compromise in Python. A fully manual swap-based rotation algorithm is possible, but it is usually less readable and not obviously better in normal application code.

Normalize the Rotation Count

Always reduce k modulo the list length:

python
k %= len(values)

That handles cases such as:

  • 'k larger than the list size'
  • multiple full turns
  • cleaner boundary behavior

Without normalization, rotations such as k = 1_000_000 on a five-element list do more work than needed or require extra logic.

Choose the Method by Use Case

A simple rule of thumb works well:

  • use slicing for a one-off rotated copy
  • use slicing assignment for in-place mutation
  • use deque for repeated rotations

This is better than searching for one universally "most efficient" answer, because the best choice depends on how the list is used after the rotation.

Common Pitfalls

  • Forgetting to normalize k with modulo, which makes large rotation counts awkward.
  • Using list slicing inside a tight loop when a deque would fit the repeated-rotation workload better.
  • Rebinding the list to a rotated copy when callers expected the original list object to be mutated.
  • Writing a complicated manual algorithm when simple slicing would be clearer and fast enough.
  • Not handling the empty-list case, which leads to division by zero during modulo.

Summary

  • For one-off list rotation, slicing is usually the cleanest Python solution.
  • For repeated rotation operations, collections.deque is often the better data structure.
  • Use slicing assignment if you must preserve the original list object.
  • Normalize the rotation count with modulo before rotating.
  • Pick the method that matches the workload instead of chasing one abstract "best" algorithm.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.