# [ python-Bugs-1446619 ] extended slice behavior inconsistent with docs

Fri Mar 10 23:40:07 CET 2006

Bugs item #1446619, was opened at 2006-03-09 11:37
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1446619&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: Python 2.4
Status: Open
Resolution: None
Priority: 5
Submitted By: Steven Bethard (bediviere)
Assigned to: Nobody/Anonymous (nobody)
Summary: extended slice behavior inconsistent with docs

Initial Comment:
I don't know whether the behavior or the docs is wrong,
but the extended slice behavior does not match the
documentation.  I found three places that talk about
extended slicing:

http://docs.python.org/ref/slicings.html
The semantics for a simple slicing are as follows... It
is not an error if i or j lie outside the range of
valid indexes (such items don't exist so they aren't
selected).
The semantics for an extended slicing are as follows...

http://docs.python.org/ref/types.html
Some sequences also support extended slicing'' with a
third step'' parameter: a[i:j:k] selects all items of
a with index x where x = i + n*k, n >= 0 and i <= x < j.

http://docs.python.org/lib/typesseq.html
s[i:j:k]   slice of s from i to j with step k   (3),(5)
...
(3) If i or j is negative, the index is relative to the
end of the string: len(s) + i or len(s) + j is
substituted. But note that -0 is still 0.
(5) The slice of s from i to j with step k is defined
as the sequence of items with index x = i + n*k such
that $0 \leq n < \frac{j-i}{k}$. In other words, the
indices are i, i+k, i+2*k, i+3*k and so on, stopping
when j is reached (but never including j). If i or j is
greater than len(s), use len(s). If i or j are omitted
then they become end'' values (which end depends on
the sign of k). Note, k cannot be zero.

Given those docs, consider this behavior:

>>> range(10)[10:0:-2]
[9, 7, 5, 3, 1]

By the Sequence Type Language Reference, [10:0:-2]
selects all items with index x where x = 10 + n*(-2), n
>= 0 and 10 <= x < 0.  Since no such values of x exist,
I conclude the result should have been an empty list.

By the Sequence Type Library Reference, [10:0:-2]
selects all items with index x = 10 + n*(-2) such that
0 <= n < (0 - 10)/(-2) = 5.  Thus I conclude that I
should get indices [10, 8, 6, 4, 2].  But this is also
wrong -- that would either have given me an IndexError,
if I stick to what's written for extended slicings, or
the list [8, 6, 4, 2] if I assume that the phrase "It
is not an error if i or j lie outside the range of
valid indexes" from the simple slicings section in the
Slicings Language Reference also applies to extended
slicings.

All the references I can find document this behavior
incorrectly.  I suggest rewording all the sections to
say something like:

"""
To get the slice of s from i to j with step k, first
determine the bounds.  If k is positive, and i or j is
greater than len(s), use len(s).  If k is negative, and
i or j is greater than len(s)-1, use len(s)-1. Note, k
cannot be zero.  If i or j are omitted then they become
end'' values (which end depends on the sign of k).

The slice of s from i to j with step k is then defined
as the sequence of items with index x = i + n*k such
that 0 <= n < (j - i)/k.  In other words, the indices
are i, i+k, i+2*k, i+3*k and so on, stopping when j is
reached (but never including j).
"""

The most important sentence above is "If k is negative,
and i or j is greater than len(s)-1, use len(s)-1."
Without this sentence, the documentation doesn't match
the behavior.  The remainder of the rewording is to
make it clear that the bounds are adjusted *before* the
indices are calculated.

----------------------------------------------------------------------

Comment By: Grant Olson (logistix)
Date: 2006-03-10 16:40

Message:
Logged In: YES
user_id=699438

You're right.  I misunderstood what you were saying.  I was
trying to point out that you wouldn't have an element '10'
but I now see that you said "indicies[10...]", not
values[10...].

Sorry.

----------------------------------------------------------------------

Comment By: Steven Bethard (bediviere)
Date: 2006-03-09 21:42

Message:
Logged In: YES
user_id=945502

logistix wrote:
> [0,1,2,3,4,5,6,7,8,9][10]
> will return 9

Huh?  Python indexing starts from 0.  Hence:

>>> range(10)[10]
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
IndexError: list index out of range

>>> [0,1,2,3,4,5,6,7,8,9][10]
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
IndexError: list index out of range

----------------------------------------------------------------------

Comment By: Grant Olson (logistix)
Date: 2006-03-09 20:42

Message:
Logged In: YES
user_id=699438

One problem in your analysis that range(10) returns the array

[0,1,2,3,4,5,6,7,8,9]

not:

[1,2,3,4,5,6,7,8,9,10]

The 10th element of the array holds the value 9.  so when x
= 10 + (0*-2), you get 10.  Then:

[0,1,2,3,4,5,6,7,8,9][10]

will return 9

----------------------------------------------------------------------

You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1446619&group_id=5470