Back to Blog
Python

python reverse vs reversed: Key Differences

python reverse vs reversed: Understand the difference between Python's list.reverse() method and the reversed() function, including memory behavior, use cases, and cod...

Pythonlistreverseiteratorsequence
Diagram contrasting Python's in-place list.reverse() with the reversed() iterator function.

When you need to reverse a sequence in Python, two common tools are the list.reverse() method and the built-in reversed() function. They look similar but behave very differently. reverse() mutates a list in place, while reversed() returns a reverse iterator. Understanding the distinction between python reverse vs reversed is essential for writing code that is both correct and efficient.

How reverse() Works on Mutable Sequences

The list.reverse() method reverses the elements of a list in place. It modifies the original list object and returns None. This means you cannot assign the result to a new variable; the change is applied directly to the list you call it on.

numbers = [1, 2, 3, 4] result = numbers.reverse() print(numbers) # [4, 3, 2, 1] print(result) # None

Because reverse() mutates the list, it is only available on mutable sequence types like list. Tuples and strings do not have this method. If you try to call it on a tuple, you get an AttributeError. The method is efficient for in-place reordering because it swaps elements from both ends, working in O(n) time with no additional memory allocation beyond a few temporary variables.

What reversed() Returns and Why It Matters

The reversed() built-in function takes a sequence and returns a reverse iterator. This iterator yields elements from the end to the beginning without modifying the original object. It works with any sequence that supports __len__ and __getitem__, or that implements __reversed__ explicitly.

numbers = [1, 2, 3, 4] rev_iter = reversed(numbers) print(rev_iter) # <list_reverseiterator object at 0x...> print(list(rev_iter)) # [4, 3, 2, 1] print(numbers) # [1, 2, 3, 4] # original unchanged

The iterator is lazy: it does not create a reversed copy of the data. Instead, it provides a way to traverse the sequence backward on demand. This is particularly useful when you only need to iterate once, as it avoids allocating a new list. However, if you need a persistent reversed list, you must convert the iterator to a list with list(reversed(seq)).

Comparing Memory and Runtime Behavior

The most significant difference between reverse() and reversed() lies in memory usage. reverse() operates in place, so it does not allocate a new list. It is ideal when you want to permanently reorder a list and do not need the original order afterward. reversed() creates an iterator object, which is lightweight, but iterating over it still accesses the original sequence. If you convert the iterator to a list, you allocate a new list with the same number of elements, doubling memory usage temporarily.

ApproachModifies original?ReturnsMemory overheadUse case
list.reverse()YesNoneO(1)Reorder list permanently
reversed(seq)NoIteratorO(1) for iterator, O(n) if converted to listOne-time backward iteration
seq[::-1]NoNew listO(n)Create a reversed copy

For large collections, the choice can affect peak memory usage. If you only need to loop backward once, reversed() is the most memory-efficient. If you need a reversed copy that you will keep, slicing [::-1] is simpler than list(reversed(seq)), though both create a new list.

Practical Examples: Reversing Lists, Strings, and Tuples

Let's see how each approach applies to different sequence types.

Reversing a List

fruits = ['apple', 'banana', 'cherry'] fruits.reverse() print(fruits) # ['cherry', 'banana', 'apple']

To get a new reversed list without modifying the original:

fruits = ['apple', 'banana', 'cherry'] rev_fruits = list(reversed(fruits)) print(rev_fruits) # ['cherry', 'banana', 'apple'] print(fruits) # ['apple', 'banana', 'cherry']

Reversing a String

Strings are immutable, so reverse() is not available. reversed() returns a reverse iterator of characters. To get a reversed string, join the characters:

text = "hello" rev_text = ''.join(reversed(text)) print(rev_text) # "olleh"

Alternatively, slicing with a step of -1 is more concise: text[::-1].

Reversing a Tuple

Tuples are also immutable. reversed() works, and you can convert the result back to a tuple:

point = (1, 2, 3) rev_point = tuple(reversed(point)) print(rev_point) # (3, 2, 1)

Choosing the Right Approach for Your Code

The decision between reverse() and reversed() comes down to whether you need to mutate the original sequence and whether you need a persistent reversed copy.

Use list.reverse() when:

  • You have a list and want to reorder it permanently.
  • You do not need the original order afterward.
  • You want to avoid allocating a new list to save memory.

Use reversed() when:

  • You only need to iterate backward once, such as in a for loop.
  • You want to keep the original sequence intact.
  • You are working with an immutable sequence like a string or tuple.
  • You need to pass a reverse iterator to a function that accepts an iterable.

If you need a reversed copy of a list, list(reversed(seq)) and seq[::-1] are equivalent in outcome, but slicing is more readable and slightly faster because it is implemented in C. For strings, text[::-1] is the idiomatic way to reverse.

Common Pitfalls and Edge Cases

One common mistake is assuming reversed() returns a list. It does not. Forgetting to convert the iterator to a list or tuple leads to unexpected behavior when you try to index it or print it. Another pitfall is calling reverse() on a tuple or string, which raises an AttributeError because those types are immutable.

Also note that reversed() requires the sequence to have a known length. Generators and other iterables without __len__ are not supported. For example, reversed(range(10)) works because range is a sequence, but reversed(x for x in range(10)) raises a TypeError because a generator has no length.

Performance Considerations for Large Collections

When working with large lists, the performance difference between reverse() and reversed() is primarily about memory, not speed. reverse() swaps elements in place, which is O(n) time and O(1) extra space. reversed() creates an iterator in O(1) time, but iterating over all elements is still O(n). If you convert the iterator to a list, you add O(n) time and O(n) memory for the new list.

For very large sequences, avoid creating a full reversed copy unless you need to keep it. If you only need to process elements in reverse order, use reversed() in a loop:

for item in reversed(large_list): process(item)

This avoids duplicating the entire list in memory. If you must have a reversed copy, consider whether you can process the original list in place with reverse() and then restore it later if needed, but that adds complexity. The simplest and most memory-efficient approach for one-time backward iteration is reversed().

python reverse vs reversed: Key Differences Explained | RYUSLOG DEV