diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index bdd79e37ba386..2f0b6ab0662dd 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1649,7 +1649,8 @@ def _setitem_with_indexer_split_path(self, indexer, value, name: str): value = self._align_series(indexer, value) # Ensure we have something we can iterate over - ilocs = self._ensure_iterable_column_indexer(indexer[1]) + info_axis = indexer[1] + ilocs = self._ensure_iterable_column_indexer(info_axis) pi = indexer[0] lplane_indexer = length_of_indexer(pi, self.obj.index) @@ -1673,6 +1674,12 @@ def _setitem_with_indexer_split_path(self, indexer, value, name: str): # We are trying to set N values into M entries of a single # column, which is invalid for N != M # Exclude zero-len for e.g. boolean masking that is all-false + + if len(value) == 1 and not is_integer(info_axis): + # This is a case like df.iloc[:3, [1]] = [0] + # where we treat as df.iloc[:3, 1] = 0 + return self._setitem_with_indexer((pi, info_axis[0]), value[0]) + raise ValueError( "Must have equal len keys and value " "when setting with an iterable" diff --git a/pandas/tests/indexing/multiindex/test_setitem.py b/pandas/tests/indexing/multiindex/test_setitem.py index f95eac57e9140..e5d114d5a9b18 100644 --- a/pandas/tests/indexing/multiindex/test_setitem.py +++ b/pandas/tests/indexing/multiindex/test_setitem.py @@ -210,6 +210,12 @@ def test_multiindex_assignment(self): with pytest.raises(ValueError, match=msg): df.loc[4, "c"] = [0] + # But with a length-1 listlike column indexer this behaves like + # `df.loc[4, "c"] = 0 + df.loc[4, ["c"]] = [0] + assert (df.loc[4, "c"] == 0).all() + + def test_groupby_example(self): # groupby example NUM_ROWS = 100 NUM_COLS = 10