Skip to content

Commit 54470f3

Browse files
kittokujreback
authored andcommitted
BUG: unexpected assign by a single-element list (GH19474) (#20732)
1 parent 23bc217 commit 54470f3

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

doc/source/whatsnew/v0.23.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,7 @@ Indexing
11131113
- Bug in :meth:`DataFrame.first_valid_index` and :meth:`DataFrame.last_valid_index` in presence of entire rows of NaNs in the middle of values (:issue:`20499`).
11141114
- Bug in :class:`IntervalIndex` where some indexing operations were not supported for overlapping or non-monotonic ``uint64`` data (:issue:`20636`)
11151115
- Bug in ``Series.is_unique`` where extraneous output in stderr is shown if Series contains objects with ``__ne__`` defined (:issue:`20661`)
1116+
- Bug in ``.loc`` assignment with a single-element list-like incorrectly assigns as a list (:issue:`19474`)
11161117
- Bug in partial string indexing on a ``Series/DataFrame`` with a monotonic decreasing ``DatetimeIndex`` (:issue:`19362`)
11171118

11181119
MultiIndex

pandas/core/indexing.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,8 @@ def setter(item, v):
532532

533533
def can_do_equal_len():
534534
""" return True if we have an equal len settable """
535-
if not len(labels) == 1 or not np.iterable(value):
535+
if (not len(labels) == 1 or not np.iterable(value) or
536+
is_scalar(plane_indexer[0])):
536537
return False
537538

538539
l = len(value)

pandas/tests/indexing/test_iloc.py

+16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from pandas import Series, DataFrame, date_range, concat, isna
1111
from pandas.util import testing as tm
1212
from pandas.tests.indexing.common import Base
13+
from pandas.api.types import is_scalar
1314

1415

1516
class TestiLoc(Base):
@@ -526,6 +527,21 @@ def test_iloc_setitem_list_of_lists(self):
526527
B=[5, 6, 11, 13, 9]))
527528
tm.assert_frame_equal(df, expected)
528529

530+
@pytest.mark.parametrize(
531+
'indexer', [[0], slice(None, 1, None), np.array([0])])
532+
@pytest.mark.parametrize(
533+
'value', [['Z'], np.array(['Z'])])
534+
def test_iloc_setitem_with_scalar_index(self, indexer, value):
535+
# GH #19474
536+
# assigning like "df.iloc[0, [0]] = ['Z']" should be evaluated
537+
# elementwisely, not using "setter('A', ['Z'])".
538+
539+
df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B'])
540+
df.iloc[0, indexer] = value
541+
result = df.iloc[0, 0]
542+
543+
assert is_scalar(result) and result == 'Z'
544+
529545
def test_iloc_mask(self):
530546

531547
# GH 3631, iloc with a mask (of a series) should raise

pandas/tests/indexing/test_loc.py

+16
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from pandas import Series, DataFrame, Timestamp, date_range, MultiIndex, Index
1212
from pandas.util import testing as tm
1313
from pandas.tests.indexing.common import Base
14+
from pandas.api.types import is_scalar
1415

1516

1617
class TestLoc(Base):
@@ -555,6 +556,21 @@ def test_loc_setitem_frame_multiples(self):
555556
df.loc[2:4] = rhs
556557
tm.assert_frame_equal(df, expected)
557558

559+
@pytest.mark.parametrize(
560+
'indexer', [['A'], slice(None, 'A', None), np.array(['A'])])
561+
@pytest.mark.parametrize(
562+
'value', [['Z'], np.array(['Z'])])
563+
def test_loc_setitem_with_scalar_index(self, indexer, value):
564+
# GH #19474
565+
# assigning like "df.loc[0, ['A']] = ['Z']" should be evaluated
566+
# elementwisely, not using "setter('A', ['Z'])".
567+
568+
df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B'])
569+
df.loc[0, indexer] = value
570+
result = df.loc[0, 'A']
571+
572+
assert is_scalar(result) and result == 'Z'
573+
558574
def test_loc_coerceion(self):
559575

560576
# 12411

0 commit comments

Comments
 (0)