Skip to content

BUG: Fix DataFrame.at/iat raising ValueError when storing list-like in a single cell#65311

Open
tinezivic wants to merge 2 commits intopandas-dev:mainfrom
tinezivic:fix-at-iat-list-like-setitem
Open

BUG: Fix DataFrame.at/iat raising ValueError when storing list-like in a single cell#65311
tinezivic wants to merge 2 commits intopandas-dev:mainfrom
tinezivic:fix-at-iat-list-like-setitem

Conversation

@tinezivic
Copy link
Copy Markdown
Contributor

Problem

DataFrame.at and DataFrame.iat raise ValueError when storing a list-like
value (list, tuple, np.ndarray, etc.) into a single cell of a column that
either does not yet exist or has a non-object dtype.

>>> df = pd.DataFrame({"A": [1, 2, 3]})
>>> df.at["a", "B"] = [10, 20, 30]  # new column → ValueError
>>> df.at["b", "A"] = [100, 200]    # int64 column → ValueError
>>> df.iat[0, 0] = [99, 88, 77]     # iat → ValueError

Root cause

_set_value in frame.py falls into the except branch and calls
.loc[index, col] = value. pandas .loc interprets a list-like value as a
multi-row assignment (set multiple rows), not a single-cell assignment, which
raises ValueError: Must have equal len keys and value.

Columns with object dtype already work because column_setitem in the try
block succeeds — they never reach the broken .loc fallback.

Fix

Intercept list-like values (excluding dict, which has special .loc
semantics, and slice, which is used for row-level assignment) before the
try/except block. Ensure the column has object dtype first — casting if it
exists with a non-object dtype, or creating a new object-dtype column if it
does not — then call _mgr.column_setitem directly.

AI Disclosure

I used GitHub Copilot (Claude Sonnet 4.6) to develop this pull request end-to-end:
root cause analysis, fix implementation, tests, and whatsnew entry. I prompted it
to follow AGENTS.md. I reviewed all generated code and understand the changes made.

Comment thread pandas/core/frame.py Outdated
not isinstance(cols_droplevel, MultiIndex)
and is_string_dtype(cols_droplevel.dtype)
and not cols_droplevel.any()
and (cols_droplevel == "").all()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is unrelated, seems to have snuck in to several of your PRs?

Copy link
Copy Markdown
Contributor Author

@tinezivic tinezivic Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks for catching this. I’ve reverted the unrelated changes that slipped in from #62518 / #65118, including:

  • the cols_droplevel check (restored to not .any())
  • the allow_duplicates signature/type changes in insert()
  • the allow_duplicates signature/type changes in reset_index()
  • the related allow_duplicates guard logic

This PR now contains only the #61223 at/iat list-like single-cell fix. Revert commit: 36e9f68.

…n a single cell

list-like values (list, tuple, ndarray, etc.) stored via .at or .iat into
a column that does not yet exist or has a non-object dtype raised
ValueError because the except-branch fell through to .loc/.iloc, which
interprets list-like as a multi-row assignment.

Fix: intercept is_list_like values before the try/except in _set_value.
Ensure object dtype (cast existing column or create new one), then call
_mgr.column_setitem directly.

dict values are excluded (special .loc semantics).
col=slice is excluded to preserve InvalidIndexError for row-level
assignment (df.at[row] = list with no column specified).

Closes pandas-dev#61223

STY: ruff format + fix whatsnew sort order

TYP: add cast('int', icol) to column_setitem call in _set_value try block

STY: wrap long line in _set_value try block (E501)

STY: ruff format if condition in _set_value

CLN: revert unrelated allow_duplicates and cols_droplevel changes
@tinezivic tinezivic force-pushed the fix-at-iat-list-like-setitem branch from 36e9f68 to d418235 Compare April 22, 2026 15:40
@tinezivic tinezivic force-pushed the fix-at-iat-list-like-setitem branch from d418235 to f519f8e Compare April 22, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: setting item to iterable with .at fails when column doesn't exist or has wrong dtype

2 participants