{"record":{"id":"e09a5c6f1bffdf27","repo":"pola-rs/polars","slug":"the-truth-value-of-a-series-is-ambiguous-here-are-some","errorCode":null,"errorMessage":"the truth value of a Series is ambiguous\n\nHere are some things you might want to try:\n- instead of `if s`, use `if not s.is_empty()`\n- instead of `s1 and s2`, use `s1 & s2`\n- instead of `s1 or s2`, use `s1 | s2`\n- instead of `s in [y, z]`, use `s.is_in([y, z])`","messagePattern":"the truth value of a Series is ambiguous\n\nHere are some things you might want to try:\n- instead of `if s`, use `if not s\\.is_empty\\(\\)`\n- instead of `s1 and s2`, use `s1 & s2`\n- instead of `s1 or s2`, use `s1 \\| s2`\n- instead of `s in \\[y, z\\]`, use `s\\.is_in\\(\\[y, z\\]\\)`","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/series/series.py","lineNumber":638,"sourceCode":"        Examples\n        --------\n        >>> s = pl.Series(\"a\", [1, 2, 3])\n        >>> s.shape\n        (3,)\n        \"\"\"\n        return (self._s.len(),)\n\n    def __bool__(self) -> NoReturn:\n        msg = (\n            \"the truth value of a Series is ambiguous\"\n            \"\\n\\n\"\n            \"Here are some things you might want to try:\\n\"\n            \"- instead of `if s`, use `if not s.is_empty()`\\n\"\n            \"- instead of `s1 and s2`, use `s1 & s2`\\n\"\n            \"- instead of `s1 or s2`, use `s1 | s2`\\n\"\n            \"- instead of `s in [y, z]`, use `s.is_in([y, z])`\\n\"\n        )\n        raise TypeError(msg)\n\n    def __getstate__(self) -> bytes:\n        return self._s.__getstate__()\n\n    def __setstate__(self, state: bytes) -> None:\n        self._s = Series()._s  # Initialize with a dummy\n        self._s.__setstate__(state)\n\n    def __str__(self) -> str_:\n        s_repr: str = self._s.as_str()\n        return s_repr.replace(\"Series\", f\"{self.__class__.__name__}\", 1)\n\n    def __repr__(self) -> str_:\n        return self.__str__()\n\n    def __len__(self) -> int:\n        return self.len()\n","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/py-polars/src/polars/series/series.py#L620-L656","documentation":"Polars refuses to convert a multi-element Series to a single boolean, because the result would be ambiguous (does `if s` mean 'non-empty', 'all true', or 'any true'?). Series.__bool__ deliberately raises TypeError with guidance pointing to the intended alternatives. This mirrors pandas' classic 'truth value of a Series is ambiguous' error, which almost always indicates a Python boolean operator was used where an elementwise one was meant.","triggerScenarios":"Using a Series in any boolean context: `if s:`, `assert s`, `s1 and s2`, `s1 or s2`, `not s`, `s in [y, z]`, or `bool(s)` — anything that invokes bool() on the Series (e.g. a function expected to return a scalar actually returning a Series, then used in `if`).","commonSituations":"Translating scalar if-statements from pandas/numpy code; chaining conditions with `and`/`or` instead of `&`/`|`; membership checks written as `x in [s1, s2]`; filtering results expected to be scalars but returned as one-element Series.","solutions":["Replace boolean operators with elementwise ones: `s1 and s2` -> `s1 & s2`, `s1 or s2` -> `s1 | s2`, `not s` -> `~s` (wrap compound comparisons in parentheses due to precedence).","If the intent was an emptiness check, use `if not s.is_empty():` or `if len(s) == 0:`.","If the intent was membership, use `s.is_in([y, z])` instead of `s in [y, z]`.","If you expected a scalar, extract it explicitly before the boolean context: `if s.item():` (fails loudly if length != 1), or use `s.any()`, `s.all()`, `s.sum()` as appropriate."],"exampleFix":"// before\nif (s > 0) and (s < 10):   # TypeError: the truth value of a Series is ambiguous\n    ...\n\n// after\nmask = (s > 0) & (s < 10)\nif mask.all():\n    ...","handlingStrategy":"type-guard","validationCode":"assert isinstance(x, pl.Series)\nif not isinstance(x, bool):\n    # a Series in a boolean context will raise; reduce explicitly first\n    x = x.all()  # or x.any() / x.item(), depending on intent","typeGuard":"def is_scalar_bool(v) -> bool:\n    return isinstance(v, bool)  # only bare bools are safe in if/and/or/not","tryCatchPattern":"try:\n    if s and other:\n        ...\nexcept TypeError as e:\n    if 'truth value of a Series is ambiguous' in str(e):\n        if (s & other).all():\n            ...\n    else:\n        raise","preventionTips":["Never use a Series directly in if/and/or/not; always reduce with .all(), .any(), or .item() when a scalar is intended.","Use elementwise operators & | ~ for combining Series masks, with parentheses around each comparison.","Replace `x in [series_list]` membership tests with series.is_in([...]).","Check function return types: prefer .item() over a length-1 Series when a scalar is expected.","Enable type checkers (mypy/pyright) so Series-vs-bool misuse is caught statically."],"tags":["python","polars","boolean-ambiguity","operator-misuse"],"backgroundTag":"truth-value-ambiguous","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}