fluttersmith/py-snippetsGitHub ↗

Check two lists hold the same items

Compare two collections regardless of order, counting duplicates, in linear time.

Lists#validation#countingO(n + m) time✓ 3 examples pass on 3.11–3.14

Order doesn’t matter, but counts do: [1, 1, 2] and [1, 2, 2] are different, which set(a) == set(b) misses.

have_same_contents.py✓ ruff · mypy --strict
from collections import Counter
from collections.abc import Hashable, Iterable


def have_same_contents(a: Iterable[Hashable], b: Iterable[Hashable]) -> bool:
    """Return ``True`` if ``a`` and ``b`` hold the same values, in any order."""
    return Counter(a) == Counter(b)
  1. compares counts per value in O(n), not O(n²)
examples✓ 3 doctests · 3.11–3.14
passed on Python 3.11 to 3.14: >>> have_same_contents([1, 2, 4], [2, 4, 1])Truepassed on Python 3.11 to 3.14: >>> have_same_contents([1, 1, 2], [1, 2, 2])Falsepassed on Python 3.11 to 3.14: >>> have_same_contents([], ())True
Edit the function or the examples and run the doctests here, on Python 3.14. Python loads only when you click (about 7 MB, cached after the first time).

How it works

  • Two Counters are equal when every value has the same count.
  • That’s one pass over each input. Calling list.count() per value, as the original did, is O(n²).
  • Needs hashable items; for unhashable ones, compare sorted(a) == sorted(b).

Complexity: O(n + m) time, O(n + m) space

Importfrom pysnippets.lists.have_same_contents import have_same_contentsNo dependencies: copy have_same_contents.py into your project, or clone the repo.

Adapted from have-same-contents in 30-seconds-of-python by the 30 seconds of code contributors, CC BY 4.0. Changed: Rewritten with Counter (O(n) instead of O(n²)); typed. Suggest an edit.