Explain Codes LogoExplain Codes Logo

Efficient way to rotate a list in Python

python
deque
numpy
performance
Anton ShumikhinbyAnton Shumikhin·Feb 6, 2025
TLDR

To rotate a list in Python, slice notation makes it easy: rotated_list = lst[n:] + lst[:n]. This approach neatly splits and reconstructs the list at the n index.

rotated_list = [1, 2, 3, 4, 5][2:] + [1, 2, 3, 4, 5][:2] # Result: [3, 4, 5, 1, 2]

This method is both swift and graceful, accommodating whatever rotation step n you choose.

Cue the deque

The Python collections.deque is a double-ended queue designed for swift appends and pops on both ends - it's like a revolving door, but with data.

from collections import deque my_list = deque([1, 2, 3, 4, 5]) my_list.rotate(2) # Result: deque([4, 5, 1, 2, 3])

Using collections.deque and its rotate() method allows in-place, O(1) complexity rotations. It's like being able to cut the line, regardless of length!

The might of numpy

Big data meet your match, NumPy is in town. Use numpy.roll for efficient large dataset rotation that works faster than a coffee-induced coder.

import numpy as np large_list = np.arange(1, 1000001) rotated_list = np.roll(large_list, shift=2) # Rotates the list like it's being spinned on a DJ's turntable

NumPy is the go-to when high-performance computing decides to swing by Python’s humble abode.

Slicing vs. deque: who wins?

List slicing is nice and easy. Attracts everyone like free snacks at office. But when dealing with large lists, you might feel the sting of increased time complexity. In contrast, deque keeps on moving, unconcerned about list size.

Let's evaluate performance:

# Slicing, O(k + n) complexity for k rotations and list of n size sliced_list = my_list[k:] + my_list[:k] # Deque rotate, O(1) complexity, it really doesn't care how many items or rotations you've got my_deque.rotate(k)

The winner in maximum efficiency scenarios? Deque, hands down!

Modulo magic in slicing

Imagine rotating a list so many times, it may run out of breath. That's when modulo arithmetic saves the day ensuring smooth rotations, no index errors:

k %= len(my_list) # Modulo for rotation count larger than list size, keeps your list from getting dizzy rotated_list = my_list[k:] + my_list[:k]

It wraps the rotation around the list like a scarf on a cold day.

In-place rotation

Sometimes, rotating a list in-place is like trying to save room in your luggage. Instead of slicing, use the dynamic duo append() and pop(0):

my_list.append(my_list.pop(0)) # Rotates by 1 in-place, because why not!?

Remember, though, that pop(0) is less efficient than deque operations due to the O(n) time complexity of shifting list elements. But hey, nothing wrong with a little extra effort!

Rotate using pop with index

If single-item rotations are what you need, pop() combined with an optional index parameter is as flexible as gymnasts on list manipulation:

my_list.insert(0, my_list.pop(-1)) # Rotates right by 1

This method keeps the original list structure intact, no additional memory needed.