Skip to content

REF: simplify Series.__setitem__ #41912

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 18, 2021
46 changes: 21 additions & 25 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -1074,6 +1078,7 @@ def __setitem__(self, key, value) -> None:

except (InvalidIndexError, 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
Expand Down Expand Up @@ -1102,34 +1107,25 @@ 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)

else:
assert not isinstance(key, tuple)
assert not isinstance(key, tuple)

if is_scalar(key):
key = [key]
elif is_iterator(key):
# Without this, the call to infer_dtype will consume the generator
key = list(key)
if is_scalar(key):
key = [key]
elif is_iterator(key):
# Without this, the call to infer_dtype will consume the generator
key = list(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__
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)
Expand All @@ -1140,7 +1136,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)
Expand Down