2

I usually use numpy that automatically broadcasts in many cases, and got baffled by the behavior of similar code using lists in base python.

Numpy case

aa = np.zeros((10)).astype('U')
aa[0:5] = ''
aa
# array(['', '', '', '', '', '0.0', '0.0', '0.0', '0.0', '0.0'], dtype='<U32')

What I tripped on in base Python

bb = ['0.0']*10
bb[0:5] = ''
bb
# ['0.0', '0.0', '0.0', '0.0', '0.0']

Note: It shortens the list!!
What I should have done

cc = ['0.0']*10
cc[0:5] = ['']*5
cc
# ['', '', '', '', '', '0.0', '0.0', '0.0', '0.0', '0.0']

I get that lists dont broadcast stuff and does things elementwise. Probably good to keep that consistent. But why doesnt bb[0:5] = '' just throw an error? bb[0:5] = None would have made some sense, but that instead throws me TypeError.

bb[0:5] = '' described in words becomes something like, "replace the first half of this list with an empty string". But it doesnt make sense to replace part of a list with a string. They are different types. type('') returns <class 'str'>.

Could someone enlighten me on why things are implemented like this? Has to be a good reason that I dont understand.

Anton
  • 365
  • 2
  • 12
  • 2
    A string a sequence of characters. The empty string is an empty sequence. So `bb[0:5] = ''` means "put an empty sequence in place of the slice `0:5`". Same as `bb[0:5] = []`. – khelwood Nov 09 '21 at 14:22
  • 1
    The key insights here are 1) a string is iterable (try `bb[0:5] = 'ab'`) and `None` is not, and 2) normal Python lists don't default to doing things array-wise the way numpy arrays do. – Thomas Nov 09 '21 at 14:24

0 Answers0