How to Check if Two Lists Are Reverse Equal in Python
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? True
How 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.
Slice reversal is the most readable, requires no imports, and is immediately understandable. It's the standard Pythonic way to reverse and compare lists.
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? True
reversed() is slightly more memory-friendly than slicing for very large lists because it creates an iterator rather than an immediate copy, although converting it with list() negates this advantage.
Using 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? True
Advantages 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? True
How 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
# This correctly returns False because slicing handles it
result = list1 == list2[::-1]
print(result) # False
While 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
# zip stops at the shorter list, ignoring the extra element!
result = all(a == b for a, b in zip(list1, reversed(list2)))
print(result) # True: INCORRECT!
Output:
True
This 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:
False
zip()zip() stops at the shortest iterable, so two lists of different lengths could appear to match if their overlapping portions are reverse equal. Always include len(list1) == len(list2) as a precondition.
Creating 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]
# Test cases
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
True
Edge 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 |
A list that is reverse equal to itself (like [1, 2, 1]) is called a palindromic list. You can check this with list1 == list1[::-1].
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.