diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 6d5daf5025c49..9720f3799e864 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1,5 +1,6 @@ from __future__ import annotations +import collections from contextlib import suppress import sys from typing import ( @@ -1864,6 +1865,11 @@ def _setitem_with_indexer_split_path(self, indexer, value, name: str): 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 + + # to avoid "TypeError: 'dict_values' object is not subscriptable" + if isinstance(value, collections.abc.ValuesView): + value = list(value) + return self._setitem_with_indexer((pi, info_axis[0]), value[0]) raise ValueError( diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 9b01c6b45918c..6e4f12fee1e72 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -3197,6 +3197,68 @@ def test_loc_setitem_dict_timedelta_multiple_set(self): ) tm.assert_frame_equal(result, expected) + def test_loc_setitems_dict(self): + # GH 52175 + + # single row, single column + df1 = DataFrame(index=[1, 2], columns=["a"]) + d = {"b": 1.1} + df1.loc[1, d.keys()] = d.values() + + # single row, multiple columns + df2 = DataFrame(index=[1, 2], columns=["a"]) + d = {"b": 1.1, "c": 2.2} + df2.loc[1, d.keys()] = d.values() + + # multiple rows, single column + df3 = DataFrame(index=[1, 2], columns=["a"]) + d = {"b": 1.1} + df3.loc[[1, 2], d.keys()] = d.values() + + # multiple rows, multiple columns + df4 = DataFrame(index=[1, 2], columns=["a"]) + d = {"b": 1.1, "c": 2.2} + df4.loc[[1, 2], d.keys()] = d.values() + + expected1 = DataFrame( + { + "a": Series([np.nan, np.nan], dtype="object"), + "b": [1.1, np.nan], + }, + index=[1, 2], + ) + + expected2 = DataFrame( + { + "a": Series([np.nan, np.nan], dtype="object"), + "b": [1.1, np.nan], + "c": [2.2, np.nan], + }, + index=[1, 2], + ) + + expected3 = DataFrame( + { + "a": Series([np.nan, np.nan], dtype="object"), + "b": [1.1, 1.1], + }, + index=[1, 2], + ) + + expected4 = DataFrame( + { + "a": Series([np.nan, np.nan], dtype="object"), + "b": [1.1, 1.1], + "c": [2.2, 2.2], + }, + index=[1, 2], + ) + + tm.assert_frame_equal(df1, expected1) + tm.assert_frame_equal(df2, expected2) + tm.assert_frame_equal(df3, expected3) + tm.assert_frame_equal(df4, expected4) + def test_loc_set_multiple_items_in_multiple_new_columns(self): # GH 25594 df = DataFrame(index=[1, 2], columns=["a"])