When working with Python lists, you may need to verify whether one list is the exact reverse of another. This is a common requirement in palindrome checking, data validation, symmetry verification, and algorithm problems where order matters.
Two lists are "reverse equal" when the first list's elements match the second list's elements in reverse order, for example, [5, 6, 7, 8] and [8, 7, 6, 5].
In this guide, you'll learn the most effective methods to check if two lists are reverse equal in Python, with clear examples and important edge cases.
Using Slice Reversal with == (Recommended)
The most Pythonic and concise approach uses Python's slice notation [::-1] to reverse one list and compare it directly with the other:
list1 = [5, 6, 7, 8]
list2 = [8, 7, 6, 5]
result = list1 == list2[::-1]
print(f"list1: {list1}")
print(f"list2: {list2}")
print(f"Are they reverse equal? {result}")Output:
list1: [5, 6, 7, 8]
list2: [8, 7, 6, 5]
Are they reverse equal? TrueHow it works:
list2[::-1]creates a new reversed copy oflist2→[5, 6, 7, 8].- The
==operator compares both lists element by element. - If all elements match in order, the result is
True.
Using reversed() with ==
The built-in reversed() function returns an iterator over the list in reverse order. Wrapping it in list() creates a reversed copy for comparison:
list1 = [5, 6, 7, 8]
list2 = [8, 7, 6, 5]
result = list1 == list(reversed(list2))
print(f"Are they reverse equal? {result}")Output:
Are they reverse equal? TrueUsing Element-by-Element Comparison (No Extra Memory)
If memory is a concern and you want to avoid creating a reversed copy, compare elements directly by matching indices from opposite ends:
def are_reverse_equal(list1, list2):
"""Check if two lists are reverse equal without creating a reversed copy."""
if len(list1) != len(list2):
return False
n = len(list1)
for i in range(n):
if list1[i] != list2[n - 1 - i]:
return False
return True
list1 = [5, 6, 7, 8]
list2 = [8, 7, 6, 5]
print(f"Are they reverse equal? {are_reverse_equal(list1, list2)}")Output:
Are they reverse equal? TrueAdvantages of this approach:
- O(1) auxiliary space: no reversed copy is created.
- Early exit : returns
Falseimmediately when a mismatch is found, potentially saving time on large lists that differ early. - Includes a length check upfront, which is an important optimization.
Using all() with zip(): Compact and Memory-Efficient
For a concise approach that combines element-wise comparison with early termination and no extra list creation:
list1 = [5, 6, 7, 8]
list2 = [8, 7, 6, 5]
result = len(list1) == len(list2) and all(a == b for a, b in zip(list1, reversed(list2)))
print(f"Are they reverse equal? {result}")Output:
Are they reverse equal? TrueHow it works:
- The length check prevents false positives when lists have different sizes.
zip(list1, reversed(list2))pairs each element fromlist1with the corresponding element fromlist2in reverse.all()returnsTrueonly if every pair matches, and short-circuits on the first mismatch.
Common Mistake: Forgetting to Check List Lengths
A subtle bug occurs when you compare lists of different lengths without checking their sizes first. Depending on the method, this can produce incorrect results.
Wrong approach: slice comparison without length check
list1 = [5, 6, 7]
list2 = [7, 6, 5, 4] # Different length
result = list1 == list2[::-1]
print(result) # FalseWhile slice comparison handles this correctly (reversed list2 has 4 elements vs 3 in list1), some approaches like zip() silently truncate the longer list:
Wrong approach: zip() without length check
list1 = [5, 6, 7]
list2 = [99, 7, 6, 5] # Different length, but last 3 elements reverse-match list1
result = all(a == b for a, b in zip(list1, reversed(list2)))
print(result) # True: INCORRECT!Output:
TrueThis is wrong! The lists have different lengths and shouldn't be considered reverse equal.
Correct approach: always check lengths first
list1 = [5, 6, 7]
list2 = [99, 7, 6, 5]
result = len(list1) == len(list2) and all(a == b for a, b in zip(list1, reversed(list2)))
print(result) # False: correct!Output:
FalseCreating a Reusable Function
A production-ready function with all edge cases handled:
def are_reverse_equal(list1: list, list2: list) -> bool:
"""Check if two lists are exact reverses of each other.
Args:
list1: The first list.
list2: The second list.
Returns:
True if list1 equals list2 reversed, False otherwise.
"""
if len(list1) != len(list2):
return False
return list1 == list2[::-1]
print(are_reverse_equal([5, 6, 7, 8], [8, 7, 6, 5])) # True
print(are_reverse_equal([5, 6], [7, 6])) # False
print(are_reverse_equal([], [])) # True (both empty)
print(are_reverse_equal([1], [1])) # True (single element)
print(are_reverse_equal([1, 2, 3], [3, 2])) # False (different lengths)
print(are_reverse_equal(["a", "b"], ["b", "a"])) # True (works with strings)Output:
True
False
True
True
False
TrueEdge Cases to Consider
| Scenario | list1 | list2 | Result |
|---|---|---|---|
| Normal reverse | [1, 2, 3] |
[3, 2, 1] |
True |
| Not reverse | [1, 2] |
[3, 2] |
False |
| Both empty | [] |
[] |
True |
| Single element (same) | [5] |
[5] |
True |
| Single element (different) | [5] |
[3] |
False |
| Different lengths | [1, 2, 3] |
[3, 2] |
False |
| Palindromic list | [1, 2, 1] |
[1, 2, 1] |
True |
| Duplicate elements | [1, 1, 2] |
[2, 1, 1] |
True |
Quick Comparison of Methods
| Method | Readability | Extra Memory | Early Exit | Import Required |
|---|---|---|---|---|
Slice [::-1] + == |
⭐⭐⭐ High | O(n) | ❌ No | None |
reversed() + == |
⭐⭐⭐ High | O(n) | ❌ No | None |
| Index loop | ⭐⭐ Medium | O(1) | ✅ Yes | None |
all() + zip() + reversed() |
⭐⭐ Medium | O(1) | ✅ Yes | None |
All methods have O(n) time complexity in the worst case.
Conclusion
Checking if two lists are reverse equal in Python is straightforward with the right approach:
- Slice reversal (
[::-1]) is the most Pythonic and recommended method for its clarity and simplicity. reversed()withlist()is an equally readable alternative.- Index-based comparison is ideal when memory efficiency matters and you want early termination.
all()withzip()offers a compact, memory-efficient solution but always include a length check to avoid false positives.- Always handle edge cases like empty lists, single-element lists, and different-length lists.