Check if two unordered lists are equal
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To check whether two unordered lists are equal, you first need to decide whether duplicates matter. If duplicates count, then you are really comparing multisets. If duplicates do not count, then you are comparing sets.
That distinction changes the implementation completely. Many wrong answers come from using set on lists that may contain repeated values, which silently drops duplicates and produces false positives.
If Duplicates Matter, Compare Element Counts
For most problems, this is the correct interpretation. The lists are equal if they contain the same elements with the same frequencies, regardless of order.
In Python, collections.Counter is the cleanest tool for that job:
Counter works by storing each distinct value and how many times it appears. That makes the intent obvious and handles duplicate-heavy lists correctly.
The time complexity is typically O(n) and the extra memory is also O(n) in the number of distinct values.
Sorting Is Another Correct Option
If the elements are sortable, you can sort both lists and compare the results:
This is also correct when duplicates matter, because repeated values remain present after sorting. The tradeoff is performance: sorting costs O(n log n) time.
For small lists, the difference is usually irrelevant. For large lists or streaming-like workloads, Counter is often the better choice.
Use set Only If Duplicates Do Not Matter
Sometimes the requirement is weaker: the lists should contain the same unique values, and multiplicity is irrelevant. In that case, set comparison is fine:
Notice what happened there: the first list contained two copies of 2, but the result is still True because sets discard duplicates. That is correct only if your specification says duplicates should be ignored.
What About Unhashable or Nested Elements
Counter and set require hashable elements. Plain integers, strings, and tuples are fine, but lists and dictionaries are not.
If your lists contain nested structures, you have a few options:
- normalize the values into hashable tuples before comparing
- sort by a stable key if the items are sortable after normalization
- compare serialized representations only if you fully control the format
Example with dictionaries:
The freezing step turns each dictionary into a comparable tuple of key-value pairs.
Common Pitfalls
- Using
set(a) == set(b)when duplicates matter. This is the most common mistake. - Sorting values that are not mutually comparable, such as mixed numbers and dictionaries.
- Forgetting to normalize nested mutable objects before comparison.
- Assuming list equality itself is enough. Plain
a == bis order-sensitive. - Optimizing too early. For most code, the clearest correct solution is better than a trickier micro-optimization.
Summary
- Decide first whether duplicates are significant.
- If duplicates matter, compare multisets with
Counteror with sorted lists. - If duplicates do not matter, set comparison is enough.
- Normalize nested unhashable values before using
Counterorset. - The right answer depends less on Python syntax and more on the exact definition of equality you need.

