From 9e3af680d8487be59358d475c105c783d77bc0f1 Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 9 Jun 2021 09:54:49 -0700 Subject: [PATCH 1/2] REF: handle slice earlier in Series.__setitem__ --- pandas/core/series.py | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 59ea6710ea6cd..dfc8ec9ea0c78 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1061,6 +1061,10 @@ def __setitem__(self, key, value) -> None: if key is Ellipsis: key = slice(None) + if isinstance(key, slice): + indexer = self.index._convert_slice_indexer(key, kind="getitem") + return self._set_values(indexer, value) + try: self._set_with_engine(key, value) except (KeyError, ValueError): @@ -1074,6 +1078,7 @@ def __setitem__(self, key, value) -> None: except TypeError as err: if isinstance(key, tuple) and not isinstance(self.index, MultiIndex): + # cases with MultiIndex don't get here bc they raise KeyError raise KeyError( "key of type tuple not found and not a MultiIndex" ) from err @@ -1103,31 +1108,26 @@ def _set_with_engine(self, key, value) -> None: def _set_with(self, key, value): # other: fancy integer or otherwise - if isinstance(key, slice): - indexer = self.index._convert_slice_indexer(key, kind="getitem") - return self._set_values(indexer, value) + assert not isinstance(key, tuple) - else: - assert not isinstance(key, tuple) + if is_scalar(key): + key = [key] - if is_scalar(key): - key = [key] - - if isinstance(key, Index): - key_type = key.inferred_type - key = key._values - else: - key_type = lib.infer_dtype(key, skipna=False) + if isinstance(key, Index): + key_type = key.inferred_type + key = key._values + else: + key_type = lib.infer_dtype(key, skipna=False) - # Note: key_type == "boolean" should not occur because that - # should be caught by the is_bool_indexer check in __setitem__ - if key_type == "integer": - if not self.index._should_fallback_to_positional(): - self._set_labels(key, value) - else: - self._set_values(key, value) + # Note: key_type == "boolean" should not occur because that + # should be caught by the is_bool_indexer check in __setitem__ + if key_type == "integer": + if not self.index._should_fallback_to_positional(): + self._set_labels(key, value) else: - self.loc[key] = value + self._set_values(key, value) + else: + self.loc[key] = value def _set_labels(self, key, value) -> None: key = com.asarray_tuplesafe(key) From ca2fd7194d5f91782b44a56fd02f6e881d74369e Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 9 Jun 2021 10:37:05 -0700 Subject: [PATCH 2/2] simplify --- pandas/core/series.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index dfc8ec9ea0c78..cb0f077ba5c5b 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1113,11 +1113,7 @@ def _set_with(self, key, value): if is_scalar(key): key = [key] - if isinstance(key, Index): - key_type = key.inferred_type - key = key._values - else: - key_type = lib.infer_dtype(key, skipna=False) + key_type = lib.infer_dtype(key, skipna=False) # Note: key_type == "boolean" should not occur because that # should be caught by the is_bool_indexer check in __setitem__ @@ -1138,7 +1134,7 @@ def _set_labels(self, key, value) -> None: self._set_values(indexer, value) def _set_values(self, key, value) -> None: - if isinstance(key, Series): + if isinstance(key, (Index, Series)): key = key._values self._mgr = self._mgr.setitem(indexer=key, value=value)