Skip to content

How to Compare Two Lists in Python

How to compare two Python lists for exact equality, ignore order, handle duplicates, and find differences between lists using simple and practical methods.

Comparing two lists is one of the most common operations in Python programming. Whether you're checking if two datasets are identical, finding differences between collections, or validating that a function produces the expected output, you need to understand the different ways lists can be compared, and when each approach is appropriate.

The key distinction is whether you care about element order. Two lists with the same elements in a different order might be considered equal or unequal depending on your use case. In this guide, you'll learn multiple methods to compare lists in Python, understand their differences, and choose the right one for your situation.

Direct Comparison with ==

The simplest way to compare two lists is the == operator. It checks if both lists have the same elements in the same order.

a = [1, 2, 3, 4, 5]
b = [1, 2, 3, 4, 5]
c = [5, 4, 3, 2, 1]

print(a == b)  # Same elements, same order
print(a == c)  # Same elements, different order

Output:

True
False

The == operator returns True only when both the content and order are identical. Lists a and c contain the same numbers, but since the order differs, they are not considered equal.

Order-Independent Comparison with sorted()

When you want to check if two lists contain the same elements regardless of order, sort both lists first and then compare:

a = [1, 2, 3, 4, 5]
b = [5, 4, 3, 2, 1]

result = sorted(a) == sorted(b)
print(result)

Output:

True

sorted() returns a new sorted list without modifying the originals. After sorting, both lists have the same element order, so == returns True.

a = [3, 1, 2]
b = [2, 3, 1]

print(sorted(a) == sorted(b))
print(f"a is still: {a}")
print(f"b is still: {b}")

Output:

True
a is still: [3, 1, 2]
b is still: [2, 3, 1]

Using sort() (In-Place)

The sort() method sorts the list in place and returns None. Be careful with comparisons:

a = [3, 1, 2]
b = [2, 3, 1]

a.sort()
b.sort()

print(a == b)

Output:

True

Using collections.Counter() for Frequency-Aware Comparison

Counter from the collections module counts the occurrences of each element. This is the best method when order doesn't matter but duplicates do.

from collections import Counter

a = [1, 2, 2, 3]
b = [3, 2, 1, 2]
c = [1, 2, 3, 3]

print(Counter(a) == Counter(b))  # Same elements, same frequencies
print(Counter(a) == Counter(c))  # Different frequencies of 2 and 3

Output:

True
False

Counter correctly identifies that a and b have the same elements with the same frequencies (two 2s, one 1, one 3), while c has a different distribution.

Why Counter Is Better Than set for Duplicates

from collections import Counter

a = [1, 2, 2, 3]
b = [1, 2, 3]

print(f"set comparison:     {set(a) == set(b)}")
print(f"Counter comparison: {Counter(a) == Counter(b)}")

Output:

set comparison:     True
Counter comparison: False

set loses duplicate information, so it incorrectly reports the lists as equal. Counter preserves frequency counts and correctly identifies the difference.

Using set() for Unique Element Comparison

Convert both lists to sets when you want to check if they contain the same unique elements, ignoring both order and duplicates:

a = [1, 2, 2, 3, 3, 3]
b = [3, 2, 1]

print(set(a) == set(b))

Output:

True

Finding Differences with Sets

Sets also make it easy to find elements that exist in one list but not the other:

a = [1, 2, 3, 4, 5]
b = [3, 4, 5, 6, 7]

set_a = set(a)
set_b = set(b)

print(f"Only in a:  {set_a - set_b}")
print(f"Only in b:  {set_b - set_a}")
print(f"In both:    {set_a & set_b}")

Output:

Only in a:  {1, 2}
Only in b:  {6, 7}
In both:    {3, 4, 5}

Element-Wise Comparison with all() and zip()

To compare corresponding elements at each position, use all() with zip(). This approach is useful when you need position-aware equality:

a = [1, 2, 3, 4, 5]
b = [1, 2, 3, 4, 5]
c = [1, 2, 99, 4, 5]

print(all(x == y for x, y in zip(a, b)))
print(all(x == y for x, y in zip(a, c)))

Output:

True
False

Practical Example: Finding What Changed

A common real-world task is comparing two versions of a list and identifying additions, removals, and common elements:

from collections import Counter

def compare_lists(list1, list2):
    """Compare two lists and return a detailed report."""
    counter1 = Counter(list1)
    counter2 = Counter(list2)

    added = counter2 - counter1
    removed = counter1 - counter2
    common = counter1 & counter2

    return {
        'are_equal': counter1 == counter2,
        'added': list(added.elements()),
        'removed': list(removed.elements()),
        'common': list(common.elements())
    }


old_inventory = ['apple', 'banana', 'apple', 'cherry', 'date']
new_inventory = ['apple', 'banana', 'cherry', 'cherry', 'elderberry']

result = compare_lists(old_inventory, new_inventory)

print(f"Equal: {result['are_equal']}")
print(f"Added: {result['added']}")
print(f"Removed: {result['removed']}")
print(f"Common: {result['common']}")

Output:

Equal: False
Added: ['cherry', 'elderberry']
Removed: ['apple', 'date']
Common: ['apple', 'banana', 'cherry']

Quick Comparison of Methods

Method Order Matters Handles Duplicates Best For
== ✅ Yes ✅ Yes Exact equality (content + order)
sorted() + == ❌ No ✅ Yes Same elements regardless of order
Counter() ❌ No ✅ Yes Frequency-aware comparison
set() ❌ No ❌ Ignores duplicates Unique element comparison
all() + zip() ✅ Yes ✅ Yes Position-by-position comparison

Conclusion

Python offers several ways to compare two lists, and choosing the right method depends on what "equal" means for your use case:

  • Use == when both order and content must match exactly. The simplest and most common choice.
  • Use sorted() when you want to ignore order but still account for duplicates.
  • Use Counter() for the most robust order-independent comparison that correctly handles duplicate elements.
  • Use set() only when you want to compare unique elements and intentionally ignore duplicates.
  • Use all() with zip() for element-wise positional comparison, but always add a length check to avoid silent mismatches.

For most everyday comparisons, == or sorted() will be sufficient. When working with data that may contain duplicates and order variation, Counter() is the safest and most reliable choice.

Navigation