{"record":{"id":"40671dcd981af9cd","repo":"pandas-dev/pandas","slug":"expression-objects-are-not-iterable","errorCode":null,"errorMessage":"Expression objects are not iterable","messagePattern":"Expression objects are not iterable","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/col.py","lineNumber":360,"sourceCode":"                    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\n    ``pd.col(col_name)``.\n\n    .. versionadded:: 3.0.0","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/col.py#L342-L378","documentation":"Raised by Expression.__iter__ (typed NoReturn) when code tries to iterate a pandas.api.typing.Expression. An Expression is a deferred column descriptor, not a container of values, so iteration has no meaning until it is evaluated against a DataFrame. Any for loop, unpacking, list(), tuple(), or *expr spread triggers it.","triggerScenarios":"for v in pd.col('a'): ...; list(pd.col('a')); a, b = pd.col('a'); zip(pd.col('a'), other); passing an Expression to a function that iterates its argument.","commonSituations":"Confusing pd.col('a') (deferred) with df['a'] (materialized); writing generic code that iterates any input and accidentally receiving an Expression.","solutions":["Evaluate against a DataFrame first: series = pd.col('a')._eval_expression(df), then iterate series.","Use df['a'] directly when you already have the DataFrame in scope.","Type-check inputs in generic helpers: reject pandas.api.typing.Expression before iterating."],"exampleFix":"// before\nfor v in pd.col('speed'):\n    ...\n// after\nfor v in df['speed']:\n    ...","handlingStrategy":"type-guard","validationCode":"from pandas.api.typing import Expression\nif isinstance(x, Expression):\n    raise TypeError('evaluate Expression against a DataFrame before iterating')","typeGuard":"def is_expression(x) -> bool:\n    from pandas.api.typing import Expression\n    return isinstance(x, Expression)","tryCatchPattern":null,"preventionTips":["Differentiate pd.col('x') (deferred) from df['x'] (materialized) before iteration.","Type-check inputs in generic iteration helpers."],"tags":["type-error","expression","col","iteration","deferred"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}