pandas-dev/pandas · error · TypeError
Expected Hashable, got: {type(col_name)}
Error message
Expected Hashable, got: {type(col_name)} What it means
Raised by pandas.col (pandas/core/col.py:413) when the `col_name` argument is not an instance of Hashable. pd.col stores the name for later deferred lookup against a DataFrame, so it must be a hashable label (str, int, tuple of hashables, etc.). Unhashable types like list, dict, or ndarray cannot serve as column keys and are rejected up front.
Source
Thrown at pandas/core/col.py:413
--------
You can use `col` in `assign`.
>>> df = pd.DataFrame({"name": ["beluga", "narwhal"], "speed": [100, 110]})
>>> df.assign(name_titlecase=pd.col("name").str.title())
name speed name_titlecase
0 beluga 100 Beluga
1 narwhal 110 Narwhal
You can also use it for filtering.
>>> df.loc[pd.col("speed") > 105]
name speed
1 narwhal 110
"""
if not isinstance(col_name, Hashable):
msg = f"Expected Hashable, got: {type(col_name)}"
raise TypeError(msg)
def func(df: DataFrame) -> Series:
if col_name not in df.columns:
columns_str = str(df.columns.tolist())
max_len = 90
if len(columns_str) > max_len:
columns_str = columns_str[:max_len] + "...]"
msg = (
f"Column '{col_name}' not found in given DataFrame.\n\n"
f"Hint: did you mean one of {columns_str} instead?"
)
raise ValueError(msg)
return df[col_name]
return Expression(func, f"col({col_name!r})")
View on GitHub (pinned to 71959b8cb9)
Solutions
- Pass a single hashable name: `pd.col('a')` or `pd.col(0)`.
- For multiple columns, build separate Expressions: `[pd.col(c) for c in ['a','b']]`.
- If you have a tuple column (MultiIndex level), pass the full tuple: `pd.col(('a','b'))`.
Example fix
# before pd.col(['speed','name']) # after [pd.col(c) for c in ['speed','name']]
Defensive patterns
Strategy: validation
Validate before calling
from typing import Hashable
def safe_col(name):
if not isinstance(name, Hashable):
raise TypeError(f'col_name must be Hashable, got {type(name).__name__}')
import pandas as pd
return pd.col(name) Type guard
from typing import Hashable
def is_hashable_name(name) -> bool:
try:
hash(name)
return isinstance(name, Hashable)
except TypeError:
return False Try / catch
try:
expr = pd.col(name)
except TypeError as e:
if 'Expected Hashable' in str(e):
name = name[0] if isinstance(name, (list, tuple)) and len(name) == 1 else name
expr = pd.col(name)
else:
raise Prevention
- Pass only a single hashable label (str, int, tuple) to pd.col.
- For multiple columns, build a list of Expressions.
- Validate dynamic names with isinstance(name, Hashable) first.
When it happens
Trigger: `pd.col(['a','b'])` (passing a list), `pd.col({'x':1})`, `pd.col(np.array([1,2]))`, or any mutable/unhashable object. Also `pd.col(df)` where df is a DataFrame.
Common situations: Confusing pd.col (single deferred column) with multi-column selection. Passing a dynamic list computed at runtime without picking a single element.
Related errors
- boolean value of an expression is ambiguous
- Expression objects are not iterable
- Expression objects are not copiable
- Column '{col_name}' not found in given DataFrame. Hint: did
- unsupported type: {into}
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/8eb713a7f446d9fb.
Report an issue: GitHub.