diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 4f17133ef4a8c..c85a6fd2270af 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -1091,6 +1091,7 @@ Indexing - Bug in :meth:`DataFrame.loc` when indexing with an :class:`IntervalIndex` (:issue:`19977`) - :class:`Index` no longer mangles ``None``, ``NaN`` and ``NaT``, i.e. they are treated as three different keys. However, for numeric Index all three are still coerced to a ``NaN`` (:issue:`22332`) - Bug in `scalar in Index` if scalar is a float while the ``Index`` is of integer dtype (:issue:`22085`) +- Bug in `MultiIndex.set_levels` when levels value is not subscriptable (:issue:`23273`) Missing ^^^^^^^ diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 3cccb65503378..79ac32d2f6a0b 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -389,6 +389,9 @@ def set_levels(self, levels, level=None, inplace=False, labels=[[0, 0, 1, 1], [0, 1, 0, 1]], names=[u'foo', u'bar']) """ + if is_list_like(levels) and not isinstance(levels, Index): + levels = list(levels) + if level is not None and not is_list_like(level): if not is_list_like(levels): raise TypeError("Levels must be list-like") diff --git a/pandas/tests/indexes/multi/test_get_set.py b/pandas/tests/indexes/multi/test_get_set.py index 99ab54a83636c..ff2170839b012 100644 --- a/pandas/tests/indexes/multi/test_get_set.py +++ b/pandas/tests/indexes/multi/test_get_set.py @@ -414,3 +414,17 @@ def test_set_value_keeps_names(): df.at[('grethe', '4'), 'one'] = 99.34 assert df._is_copy is None assert df.index.names == ('Name', 'Number') + + +def test_set_levels_with_iterable(): + # GH23273 + sizes = [1, 2, 3] + colors = ['black'] * 3 + index = pd.MultiIndex.from_arrays([sizes, colors], names=['size', 'color']) + + result = index.set_levels(map(int, ['3', '2', '1']), level='size') + + expected_sizes = [3, 2, 1] + expected = pd.MultiIndex.from_arrays([expected_sizes, colors], + names=['size', 'color']) + tm.assert_index_equal(result, expected)