Greetings, I want to know more about the design history of object slicings.
As in Python 3.13.0:
>>> [1:2:3]
File "<python-input-0>", line 1
[1:2:3]
^
SyntaxError: invalid syntax
>>> [::]
File "<python-input-2>", line 1
[::]
^
SyntaxError: invalid syntax
>>> [::,] # Note the comma
File "<python-input-1>", line 1
[::,] # Note the comma
^
SyntaxError: invalid syntax
In the meantime:
>>> class T:
... def __getitem__(self, item):
... return item
...
>>> s = T()
>>> s[1:2:3] # Works perfectly fine
slice(1, 2, 3)
>>> s[::] # Works perfectly fine
slice(None, None, None)
>>> s[::,]
(slice(None, None, None),) # !?
>>> s[::, ::] # Why do we even allow this? (Why not SyntaxError?)
(slice(None, None, None), slice(None, None, None))
>>> s[:,:]
(slice(None, None, None), slice(None, None, None))
According to the Python Language Reference:
[…] If the slice list contains at least one comma, the key is a tuple containing the conversion of the slice items; otherwise, the conversion of the lone slice item is the key. The conversion of a slice item that is an expression is that expression. […]
Hence, my question is: Why did we design the object slicing syntax like this?
-
Why did we allow
s[::,]
,s[::, ::]
compared to raising aSyntaxError
? What are the use cases anyway? -
Why did we allow
s[::,]
but not[::,]
? (I know object slicing and list expressions serve different purposes with similar syntax, so I understand why do we allows[::]
but not[::]
. But if the comma makes it a tuple, why don’t we allow[::,]
too? Maybe make::
a single element of the list or something like that?)
(The Disign and History FAQ does not talk about it. I also can’t find the PEP which introduces the slicing syntax. Correct me if I am wrong:) )