When you expand the value_to_be_set object to greater than one element, this error occurs:
Traceback (most recent call last):
File "<pyshell#314>", line 1, in <module>
df.loc[0, 'col1'] = value_to_be_set
File "C:\Users\rook\Projects\Sandbox\env\lib\site-packages\pandas\core\indexing.py", line 671, in __setitem__
self._setitem_with_indexer(indexer, value)
File "C:\Users\rook\Projects\Sandbox\env\lib\site-packages\pandas\core\indexing.py", line 850, in _setitem_with_indexer
self._setitem_with_indexer(new_indexer, value)
File "C:\Users\rook\Projects\Sandbox\env\lib\site-packages\pandas\core\indexing.py", line 1019, in _setitem_with_indexer
"Must have equal len keys and value "
ValueError: Must have equal len keys and value when setting with an iterable
Whereas when you call it for 'col2' after initializing the column, this doesn't occur.
Looking at my env source code for __setitem__ on 1.0.3 reveals:
def __setitem__(self, key, value):
if isinstance(key, tuple):
key = tuple(com.apply_if_callable(x, self.obj) for x in key)
else:
key = com.apply_if_callable(key, self.obj)
indexer = self._get_setitem_indexer(key)
self._setitem_with_indexer(indexer, value)
The last line of which has been changed to below in 1.0.4 current branch on github:
def __setitem__(self, key, value):
# ... same as above ... #
self._has_valid_setitem_indexer(key)
iloc = self if self.name == "iloc" else self.obj.iloc
iloc._setitem_with_indexer(indexer, value)
However the _has_valid_setitem_indexer seem to be still in the works:
def _has_valid_setitem_indexer(self, indexer) -> bool:
"""
Validate that a positional indexer cannot enlarge its target
will raise if needed, does not modify the indexer externally.
Returns
-------
bool
"""
if isinstance(indexer, dict):
raise IndexError("iloc cannot enlarge its target object")
else:
if not isinstance(indexer, tuple):
indexer = _tuplify(self.ndim, indexer)
for ax, i in zip(self.obj.axes, indexer):
if isinstance(i, slice):
# should check the stop slice?
pass
elif is_list_like_indexer(i):
# should check the elements?
pass
elif is_integer(i):
if i >= len(ax):
raise IndexError("iloc cannot enlarge its target object")
elif isinstance(i, dict):
raise IndexError("iloc cannot enlarge its target object")
return True
In any case, I would suggest submit this as a bug since it is still reproducible in the latest version 1.0.4:
>>> df.loc[0, 'col1'] = v2
>>> df['col2'] = None
>>> df.loc[0, 'col2'] = v2
>>> df
col1 col2
0 1 {1}
>>> pd.__version__
'1.0.4'
The absurdity is apparent if you insert the same item to a second index:
>>> df = pd.DataFrame()
>>> df.loc[0, 'col1'] = v
>>> df.loc[1, 'col1'] = v
>>> df
col1
0 1
1 {1}
I would think using loc to set up new columns is buggy indeed due to implied unpacking.