Reverse a Python List: reverse(), reversed(), and Slicing

Python offers several ways to reverse a list, and they do not have the same ownership or return behavior. list.reverse() changes the list in place and returns None. reversed(list) returns a reverse iterator without changing the original. list[::-1] creates a shallow copy in reverse order. Choose between mutation, iteration, and copying based on what the caller needs.

Quick answer

Use items.reverse() when you own the list and want to mutate it. Use list(reversed(items)) when you need a new list from a reverse iterator. Use items[::-1] for a concise shallow copy. Use reversed(items) directly when you only need to iterate backwards and do not need to store another list.

The official Python list documentation notes that in-place list methods return None. The reversed() documentation describes the iterator form. Those return contracts explain many bugs that appear when code assigns the result of reverse().

Python list reversal comparison showing reverse reversed and slicing return values mutation and ownership
Choose in-place mutation, a reverse iterator, or a new shallow copy based on the ownership and return contract you need.

Reverse a list in place

The reverse() method reorders the existing list object. It is appropriate when the list is mutable state and all references to it should observe the new order. The method intentionally returns None, so call it as a statement.

items = [10, 20, 30, 40]
result = items.reverse()

print(items)
print(result)

A common mistake is items = items.reverse(). That assignment replaces the list reference with None. If the list should remain available, use the method on its own line and keep the original variable.

Python Pool infographic showing a list, reverse method, in-place mutation, and reversed order
list.reverse reverses the existing list in place and returns None.

Create a reversed copy with slicing

The slice expression items[::-1] returns a new list whose elements are in reverse order. The original list is unchanged. This is convenient when the caller needs random access, a list length, or a value that can be passed to code expecting a concrete list.

items = [10, 20, 30, 40]
reversed_items = items[::-1]

print(items)
print(reversed_items)
print(items is reversed_items)

The copy is shallow. The list container is new, but nested objects are still shared. Reversing a list does not clone dictionaries, lists, or custom objects inside it.

Use reversed() for iteration

reversed(items) returns an iterator that yields items from the end toward the beginning. It does not create a second list and does not mutate the original. This is a good default for a one-pass loop.

items = ["first", "second", "third"]

for item in reversed(items):
    print(item)

print(items)

An iterator is consumed as it is read. If the values must be traversed multiple times or indexed, materialize it with list(). Keeping the iterator lazy can save memory when the source is large.

Python Pool infographic mapping a list through reversed to a lazy reverse iterator
reversed returns an iterator and leaves the original list unchanged.

Choose the return type deliberately

The three forms communicate different ownership decisions. The in-place method is fastest when mutation is intended. Slicing creates a list immediately. reversed() defers iteration and may work with other reversible objects, not only lists.

items = [1, 2, 3]

in_place = items.copy()
in_place.reverse()

copied = items[::-1]
iterator = reversed(items)

print(in_place)
print(copied)
print(list(iterator))
print(items)

Do not choose a form only because it is shorter. The return value and mutation behavior are part of the function contract. A helper that returns a new list is safer for general callers than a helper that silently changes a list it did not create.

Reverse strings and other sequences

Strings do not have a reverse() method because they are immutable, but slicing can return a reversed string. The same slice syntax works for tuples and other sequence types that support slicing. The meaning of reversing user-visible Unicode text may require more care than reversing code points.

word = "Python"
reversed_word = word[::-1]

print(reversed_word)
print(word)

For text with combining marks or emoji sequences, code-point reversal can produce visually incorrect output. If the user expects grapheme-cluster-aware reversal, use a library and a documented text model instead of assuming a slice matches what a person sees.

Python Pool infographic comparing list slicing, step minus one, copy, and reversed output
list[::-1] creates a reversed shallow copy using a negative step.

Reverse a list of records safely

When records are dictionaries or objects, a reversed list still contains references to the same records. A shallow copy is enough when order is the only change. Make a deep copy only when nested values must be independent, because deep copying can be expensive and may not be meaningful for every object.

records = [
    {"id": 1, "name": "Ada"},
    {"id": 2, "name": "Grace"},
]
reverse_order = list(reversed(records))

reverse_order[0]["name"] = "Grace Hopper"
print(records[1]["name"])

The example shows that the record dictionaries are shared. If a caller should not be able to modify the original records through the returned list, define that boundary explicitly and copy the records at the appropriate depth.

Reverse while enumerating

If an index is useful while iterating, enumerate the reversed iterator. The index produced by enumerate() starts at zero for the reversed traversal; it is not automatically the original list index. Compute the original index separately when that distinction matters.

items = ["a", "b", "c"]

for reverse_index, item in enumerate(reversed(items)):
    original_index = len(items) - 1 - reverse_index
    print(reverse_index, original_index, item)

This explicit calculation is easier to review than trying to infer an index from the loop order. It also works when the list length is known and the source is not modified during iteration.

Python Pool infographic testing aliases, empty lists, iterators, nested data, and validation
Check mutation versus copy, aliasing, empty input, iterator consumption, and nested-object identity.

Common mistakes

  • Assigning the return value of list.reverse() to the list variable.
  • Expecting reversed() to return a list instead of an iterator.
  • Assuming [::-1] deep-copies nested objects.
  • Mutating a list while an iterator over it is active.
  • Reversing Unicode code points when the requirement is visual text reversal.

The pragmatic choice is simple: mutate with reverse(), lazily iterate with reversed(), or create a shallow copy with [::-1]. Make that choice explicit in the helper's name and return contract so callers know what happens to the original list.

Make the ownership contract visible

A function that returns a reversed list should usually leave its input unchanged unless mutation is the explicit purpose. Naming helpers with words such as copy, iterator, or in-place can make this contract obvious to callers. Tests should check both the returned order and the state of the original list.

When performance matters, measure the size of the data and the lifetime of the result. A reverse iterator avoids allocating another list, while a shallow copy makes later indexing and repeated iteration simpler. The right choice is a behavior decision before it is a micro-optimization.

For related list operations, compare list iteration with checking list length safely. Read python iterate through list and python list length for the related workflow.

Frequently Asked Questions

Frequently Asked Questions

How do I reverse a Python list?

Use items.reverse() to mutate the list, reversed(items) to iterate backward, or items[::-1] to create a reversed shallow copy.

Why does list.reverse() return None?

reverse() changes the existing list in place and returns None by design, so it should be called as a statement.

What does reversed() return?

reversed(items) returns an iterator that yields items from the end toward the beginning without changing the original list.

Does [::-1] make a deep copy?

No. It creates a new list container, but nested objects inside the list are still shared.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted