pandas-dev/pandas · error · ValueError
Lengths must match.
Error message
Lengths must match.
What it means
Raised inside the comparison operator built by `_cat_compare_op` when `other` is a list-like whose length differs from the Categorical and `other` is not hashable. Pandas requires element-wise comparisons against list-likes to be broadcastable (equal length). The hashable carve-out exists so a single tuple that is itself a category is treated as a scalar, not a sequence.
Solutions
- Verify `len(other) == len(cat)` before comparing; align or filter the list-like to match.
- If you meant scalar comparison, pass the scalar directly (not wrapped in a list/tuple).
- For index-aligned comparison, wrap both sides in a Series first: `pd.Series(cat) == pd.Series(other)`.
- If comparing against a single tuple-as-category, ensure the tuple is itself hashable and present in `cat.categories`.
Example fix
# before import pandas as pd cat = pd.Categorical(['a', 'b', 'c']) result = cat == ['a', 'b'] # ValueError: Lengths must match. # after (scalar) result = cat == 'a' # after (aligned list-like) result = cat == ['a', 'b', 'c']
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
from pandas.api.types import is_list_like
def safe_cat_compare(cat, other):
if is_list_like(other) and len(other) != len(cat):
raise ValueError(f"length {len(other)} != {len(cat)}; align before compare")
return cat == other Type guard
from pandas.api.types import is_list_like, is_hashable
def is_broadcastable_to(cat, other) -> bool:
if not is_list_like(other) or is_hashable(other):
return True
return len(other) == len(cat) Try / catch
try:
result = cat == other
except ValueError as e:
if "Lengths must match" in str(e):
# align lengths, then retry
...
raise Prevention
- Always confirm `len(other) == len(cat)` before element-wise comparisons against list-likes.
- Prefer Series-on-Series comparison if you want automatic index alignment.
- Wrap scalars in their natural form (not single-element lists) so they hit the hashable branch.
When it happens
Trigger: Calling any comparison operator (`==`, `!=`, `<`, `>`, `<=`, `>=`) on a Categorical with a Python list, numpy array, Series, or Index whose `len()` differs from `len(cat)` — e.g. `pd.Categorical(['a','b','c']) == ['a','b']`.
Common situations: Mismatched index alignment expectations (users assume pandas auto-aligns like Series does — it does not for raw Categorical ops), broadcasting a scalar accidentally wrapped in a list, or feeding a column from a differently-filtered DataFrame.
Related errors
- cannot broadcast result
- Cannot cast dtype to
- Cannot compare a Categorical for op
- Cannot convert float NaN to integer
- Cannot divide vectors with unequal lengths
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/d2c1d1d257abc553.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/categorical.py:137
)
from pandas import (
DataFrame,
Index,
Series,
)
def _cat_compare_op(op):
opname = f"__{op.__name__}__"
fill_value = op is operator.ne
@unpack_zerodim_and_defer(opname)
def func(self, other):
hashable = is_hashable(other)
if is_list_like(other) and len(other) != len(self) and not hashable:
# in hashable case we may have a tuple that is itself a category
raise ValueError("Lengths must match.")
if not self.ordered:
if opname in ["__lt__", "__gt__", "__le__", "__ge__"]:
raise TypeError(
"Unordered Categoricals can only compare equality or not"
)
if isinstance(other, Categorical):
# Two Categoricals can only be compared if the categories are
# the same (maybe up to ordering, depending on ordered)
msg = "Categoricals can only be compared if 'categories' are the same."
if not self._categories_match_up_to_permutation(other):
raise TypeError(msg)
if not self.ordered and not self.categories.equals(other.categories):
# both unordered and different order
other_codes = recode_for_categories(
other.codes, other.categories, self.categories, copy=FalseView on GitHub (pinned to 3b7651241d)