{"record":{"id":"c2f06d9fe05a5196","repo":"pandas-dev/pandas","slug":"boolean-value-of-an-expression-is-ambiguous","errorCode":null,"errorMessage":"boolean value of an expression is ambiguous","messagePattern":"boolean value of an expression is ambiguous","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/col.py","lineNumber":357,"sourceCode":"            evaluated = []\n            for condition, replacement in caselist:\n                if isinstance(condition, Expression):\n                    condition = condition._eval_expression(df)\n                if isinstance(replacement, Expression):\n                    replacement = replacement._eval_expression(df)\n                evaluated.append((condition, replacement))\n            return ser.case_when(evaluated)\n\n        # Keep repr compact; caselist may be large.\n        repr_str = f\"{self!r}.case_when(...)\"\n        return Expression(func, repr_str)\n\n    def __repr__(self) -> str:\n        return self._repr_str or \"Expr(...)\"\n\n    # Unsupported ops\n    def __bool__(self) -> NoReturn:\n        raise TypeError(\"boolean value of an expression is ambiguous\")\n\n    def __iter__(self) -> NoReturn:\n        raise TypeError(\"Expression objects are not iterable\")\n\n    def __copy__(self) -> NoReturn:\n        raise TypeError(\"Expression objects are not copiable\")\n\n    def __deepcopy__(self, memo: dict[int, Any] | None) -> NoReturn:\n        raise TypeError(\"Expression objects are not copiable\")\n\n\n@set_module(\"pandas\")\ndef col(col_name: Hashable) -> Expression:\n    \"\"\"\n    Generate deferred object representing a column of a DataFrame.\n\n    Any place which accepts ``lambda df: df[col_name]``, such as\n    :meth:`DataFrame.assign` or :meth:`DataFrame.loc`, can also accept","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/col.py#L339-L375","documentation":"Raised by Expression.__bool__ (pandas/core/col.py:357). `pd.col(name)` returns a deferred Expression representing a not-yet-bound column; its truth value is undefined because the column does not exist until evaluated against a DataFrame. Python calls __bool__ whenever an object is used in `if`, `and`, `or`, `not`, or ternary contexts, so this guard prevents ambiguous boolean coercion.","triggerScenarios":"Writing `if pd.col('x') > 5:` (the comparison returns an Expression, not a bool), `pd.col('x') and pd.col('y')`, or `bool(pd.col('x'))`. Also `~pd.col('x')` inside an `if`, or passing an Expression to a function that does `if value:`.","commonSituations":"Treating a deferred Expression like a concrete value. Using `pd.col` inside conditional logic instead of inside assign/loc/query which evaluate the expression against a DataFrame.","solutions":["Use the Expression only inside a context that evaluates it against a DataFrame: `df.assign(flag=pd.col('x') > 5)` or `df.loc[pd.col('x') > 5]`.","If you need a scalar boolean, first bind the expression to a frame and reduce: `bool((df['x'] > 5).any())`.","Rewrite `if expr:` logic to operate on the resolved Series after evaluation."],"exampleFix":"# before\nexpr = pd.col('speed') > 100\nif expr:\n    ...\n\n# after\ndf = df.assign(fast=pd.col('speed') > 100)","handlingStrategy":"type-guard","validationCode":"from pandas.core.col import Expression\n\ndef assert_evaluable(expr):\n    if isinstance(expr, Expression):\n        raise TypeError(\"Expression cannot be used in a boolean context; evaluate against a DataFrame first\")","typeGuard":"from pandas.core.col import Expression\n\ndef is_expression(obj) -> bool:\n    return isinstance(obj, Expression)","tryCatchPattern":"from pandas.core.col import Expression\n\ntry:\n    result = bool(obj)\nexcept TypeError as e:\n    if 'ambiguous' in str(e) and isinstance(obj, Expression):\n        # evaluate against a frame and reduce instead\n        result = bool(obj._eval_expression(df).any())\n    else:\n        raise","preventionTips":["Never use pd.col expressions in if/and/or/not; only in assign/loc/query.","Treat Expression as a deferred spec, not a concrete value.","Reduce to a scalar bool only after binding: bool((df[col] > n).any())."],"tags":["expression","pd-col","boolean","deferred","typeerror"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}