[Python-ideas] Range and slice syntax
Steven D'Aprano
steve at pearwood.info
Sun Nov 11 04:35:38 EST 2018
On Sat, Nov 10, 2018 at 10:58:02PM -0700, Nicholas Harrison wrote:
[...]
> (start:stop:step)
>
>
> Meet a range/slice object. Parentheses are required. (Its syntax in this
> regard follows exactly the same rules as a generator expression.) I say
> both range and slice because it can be used in either role.
Ranges and slices are conceptually different things. Even if they have
similar features, they are very different:
- range is a lazy sequence, which produces its values on demand;
- it supports (all? most?) of the Sequence ABC, including
membership testing and len();
- but its values are intentionally limited to integers;
- slice objects, on the other hand, are an abstraction referring
to a context-sensitive sequence of abstract indices;
- those indices can be anything you like:
py> s = slice("Surprise!", range(1, 100, 3), slice(None))
py> s.start
'Surprise!'
py> s.stop
range(1, 100, 3)
py> s.step
slice(None, None, None)
- they don't support membership testing, len() or other Sequence
operations;
- most importantly, because they are context-sensitive, we don't
even know how many indexes are included in a slice until we know
what we're slicing.
That last item is why slice objects have an indices() method that takes
a mandatory length parameter.
If slices were limited to single integer indices, then there would be an
argument that they are redundant and we could use range objects in their
place; but they aren't.
[...]
> Why is it useful? I at least find its syntax to be simple, intuitive, and
> concise -- more so than the range(...) or slice(...) alternatives.
Concise, I will grant, but *intuitive*?
I have never forgot the first time I saw Python code, and after being
told over and over again how "intuitive" it was I was utterly confused
by these mysterious list[:] and list[1:] and similar expressions. I had
no idea what they were or what they were supposed to do. I didn't even
have a name I could put to them.
At least range(x) was something I could *name* and ask sensible
questions about. I didn't even have a name for this strange
square-bracket and colon syntax, and no context for understanding what
it did. There's surely few things in Python more cryptic than
mylist = mylist[:]
until you've learned what slicing does and how it operates.
Your proposal has the same disadvantages: it is cryptic punctuation that
is meaningless until the reader has learned what it means, without even
an obvious name they can refer to.
Don't get me wrong: slice syntax is great, *once you have learned it*.
But it is a million miles from intuitive. If this proposal is a winner,
it won't be because it will make Python easier for beginners.
[...]
> sum(1:6) # instead of sum(range(1, 6))
That looks like you tried to take a slice of a sequence called "sum" but
messed up the brackets, using round instead of square.
> list(1:6)
Same.
> for i in (1:6):
Looks like a tuple done wrong.
I think this is not an improvement, unless you're trying to minimize the
number of characters in an expression.
> It also makes forming reusable slices clearer and easier:
>
> my_slice = (:6:2) # instead of slice(None, 6, 2)
"Easier" in the sense of "fewer characters to type", but "clearer"? I
don't think so.
[...]
> So here's the part that requires a little more thought.
Are you saying that so far you haven't put any thought into this
proposal?
*wink*
(You don't have to answer this part, it was just my feeble attempt at
humour.)
--
Steve
More information about the Python-ideas
mailing list