Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Slicing [N::-1]

3 views
Skip to first unread message

Joan Miller

unread,
Mar 5, 2010, 1:01:40 PM3/5/10
to
What does a slice as [N::-1] ?

It looks that in the first it reverses the slice and then it shows
only N items, right?

Could you add an example to get the same result without use `::` to
see it more clear?

Thanks in advance

Arnaud Delobelle

unread,
Mar 5, 2010, 1:12:05 PM3/5/10
to
Joan Miller <pelo...@gmail.com> writes:

>>> l = range(10)
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[7::-1]
[7, 6, 5, 4, 3, 2, 1, 0]
>>> [l[i] for i in range(7, -1, -1)]
[7, 6, 5, 4, 3, 2, 1, 0]

--
Arnaud

Steven D'Aprano

unread,
Mar 5, 2010, 1:22:59 PM3/5/10
to
On Fri, 05 Mar 2010 10:01:40 -0800, Joan Miller wrote:

> What does a slice as [N::-1] ?

Why don't you try it?

>>> s = "abcdefgh"
>>> s[4::-1]
'edcba'

The rules for extended slicing are not explained very well in the docs,
and can be confusing. In my experience, apart from [::-1] it is best to
always use a positive stride (the third number).


--
Steven

Steven D'Aprano

unread,
Mar 5, 2010, 1:28:06 PM3/5/10
to
On Fri, 05 Mar 2010 18:12:05 +0000, Arnaud Delobelle wrote:

>>>> l = range(10)
>>>> l
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>> l[7::-1]
> [7, 6, 5, 4, 3, 2, 1, 0]
>>>> [l[i] for i in range(7, -1, -1)]
> [7, 6, 5, 4, 3, 2, 1, 0]

Where does the first -1 come from? Slices are supposed to have default
values of 0 and len(seq):

>>> l[7::1]
[7, 8, 9]
>>> [l[i] for i in range(7, len(l), 1)]
[7, 8, 9]
>>> [l[i] for i in range(7, len(l), -1)]
[]


I don't believe the actual behaviour is documented anywhere.


--
Steven

Mensanator

unread,
Mar 5, 2010, 1:33:46 PM3/5/10
to
On Mar 5, 12:01 pm, Joan Miller <pelok...@gmail.com> wrote:
> What does a slice as [N::-1] ?

Starts at position N and returns all items to the start of the
list in reverse order.

>
> It looks that in the first it reverses the slice and then it shows
> only N items, right?

Wrong. It shows N+1 items. Remember, counting starts from 0.

>
> Could you add an example to get the same result without use `::` to
> see it more clear?

for i in range(8,-1,-1):print(a[i],end=' ')

although I doubt this is more clear.

>
> Thanks in advance

Mensanator

unread,
Mar 5, 2010, 1:52:28 PM3/5/10
to
On Mar 5, 12:28 pm, Steven D'Aprano <st...@REMOVE-THIS-

cybersource.com.au> wrote:
> On Fri, 05 Mar 2010 18:12:05 +0000, Arnaud Delobelle wrote:
> >>>> l = range(10)
> >>>> l
> > [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> >>>> l[7::-1]
> > [7, 6, 5, 4, 3, 2, 1, 0]
> >>>> [l[i] for i in range(7, -1, -1)]
> > [7, 6, 5, 4, 3, 2, 1, 0]
>
> Where does the first -1 come from? Slices are supposed to have default
> values of 0 and len(seq):

The only way to get a 0 from a reverse range() is to have a bound of
-1.

>
> >>> l[7::1]
> [7, 8, 9]
> >>> [l[i] for i in range(7, len(l), 1)]
> [7, 8, 9]
> >>> [l[i] for i in range(7, len(l), -1)]
>
> []
>
> I don't believe the actual behaviour is documented anywhere.

Well, it's implied. If the stopping bound in a reverse range()
is greater than the starting bound, you get an empty return.

>
> --
> Steven

Robert Kern

unread,
Mar 5, 2010, 2:10:18 PM3/5/10
to pytho...@python.org
On 2010-03-05 12:28 PM, Steven D'Aprano wrote:
> On Fri, 05 Mar 2010 18:12:05 +0000, Arnaud Delobelle wrote:
>
>>>>> l = range(10)
>>>>> l
>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>>> l[7::-1]
>> [7, 6, 5, 4, 3, 2, 1, 0]
>>>>> [l[i] for i in range(7, -1, -1)]
>> [7, 6, 5, 4, 3, 2, 1, 0]
>
> Where does the first -1 come from? Slices are supposed to have default
> values of 0 and len(seq):

Rather, they have 0 and len(seq), respectively, when the step is positive, and
len(seq)-1 and -1 when the step is negative.

>>>> l[7::1]
> [7, 8, 9]
>>>> [l[i] for i in range(7, len(l), 1)]
> [7, 8, 9]
>>>> [l[i] for i in range(7, len(l), -1)]
> []
>
>
> I don't believe the actual behaviour is documented anywhere.

True, I don't think it is.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Gary Herron

unread,
Mar 5, 2010, 4:42:01 PM3/5/10
to pytho...@python.org
Mensanator wrote:
> On Mar 5, 12:28 pm, Steven D'Aprano <st...@REMOVE-THIS-
> cybersource.com.au> wrote:
>
>> On Fri, 05 Mar 2010 18:12:05 +0000, Arnaud Delobelle wrote:
>>
>>>>>> l = range(10)
>>>>>> l
>>>>>>
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
>>>>>> l[7::-1]
>>>>>>
>>> [7, 6, 5, 4, 3, 2, 1, 0]
>>>
>>>>>> [l[i] for i in range(7, -1, -1)]
>>>>>>
>>> [7, 6, 5, 4, 3, 2, 1, 0]
>>>
>> Where does the first -1 come from? Slices are supposed to have default
>> values of 0 and len(seq):
>>
>
> The only way to get a 0 from a reverse range() is to have a bound of
> -1.
>

Not quite. An empty second bound goes all the way to the zero index:

>>> range(9)[2::-1]
[2, 1, 0]

Gary Herron

Terry Reedy

unread,
Mar 5, 2010, 4:46:23 PM3/5/10
to pytho...@python.org
On 3/5/2010 2:10 PM, Robert Kern wrote:

> Rather, they have 0 and len(seq), respectively, when the step is
> positive, and len(seq)-1 and -1 when the step is negative.

>> I don't believe the actual behaviour is documented anywhere.
>


> True, I don't think it is.

There are at least two open issues.

http://bugs.python.org/issue1446619
http://bugs.python.org/issue7460

Robert Kern

unread,
Mar 5, 2010, 5:12:39 PM3/5/10
to pytho...@python.org
On 2010-03-05 13:10 PM, Robert Kern wrote:
> On 2010-03-05 12:28 PM, Steven D'Aprano wrote:
>> On Fri, 05 Mar 2010 18:12:05 +0000, Arnaud Delobelle wrote:
>>
>>>>>> l = range(10)
>>>>>> l
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>>>> l[7::-1]
>>> [7, 6, 5, 4, 3, 2, 1, 0]
>>>>>> [l[i] for i in range(7, -1, -1)]
>>> [7, 6, 5, 4, 3, 2, 1, 0]
>>
>> Where does the first -1 come from? Slices are supposed to have default
>> values of 0 and len(seq):
>
> Rather, they have 0 and len(seq), respectively, when the step is
> positive, and len(seq)-1 and -1 when the step is negative.

Well, not entirely true. [N:-1:-1] obviously doesn't work for this. Rather,
leaving the second argument in the slice empty means "go to the end if step > 0
or go to the beginning if step < 0". There is no explicit translation of the
latter because there is no numerical index for the element before the first element.

Mensanator

unread,
Mar 5, 2010, 7:09:06 PM3/5/10
to
On Mar 5, 3:42 pm, Gary Herron <gher...@islandtraining.com> wrote:

> Mensanator wrote:
>
> > The only way to get a 0 from a reverse range() is to have a bound of
> > -1.
>
> Not quite.  An empty second bound goes all the way to the zero index:

Not the same thing. You're using the bounds of the slice index.
I was refering to the bounds of the range() function.

>>> for a in range(9,-9,-1):print(a,end=' ')
9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8

To get that to stop at 0, you use a -1 as the bounds:

>>> for a in range(9,-1,-1):print(a,end=' ')
9 8 7 6 5 4 3 2 1 0

Your slice notation only works if the last (first?) number in
the range happens to be 0. What if the range bounds were variables?
You may still want to force the range's last number to be 0 by
using a constant like range(a,-1,-1) rather than just take
the last number of range(a,b,-1) by using slice notation.

Gary Herron

unread,
Mar 5, 2010, 7:34:26 PM3/5/10
to pytho...@python.org

All true and valid of course, but I was just contridicting the "the
ONLY way to get a 0" (emphasis mine) part of the statement.

Gary Herron

Mensanator

unread,
Mar 5, 2010, 9:09:59 PM3/5/10
to

Does it still contradict if you do not use the '::' as the OP
requested?

>
> Gary Herron
>
>
>
>
>
> >>  >>> range(9)[2::-1]
> >> [2, 1, 0]
>

> >> Gary Herron- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -

Gary Herron

unread,
Mar 5, 2010, 10:05:20 PM3/5/10
to pytho...@python.org
Mensanator wrote:
> On Mar 5, 6:34 pm, Gary Herron <gher...@islandtraining.com> wrote:
>
>> Mensanator wrote:
>>
>>> On Mar 5, 3:42 pm, Gary Herron <gher...@islandtraining.com> wrote:
>>>
>>>> Mensanator wrote:
>>>>
>>>>> The only way to get a 0 from a reverse range() is to have a bound of
>>>>> -1.
>>>>>
>>>> Not quite. An empty second bound goes all the way to the zero index:
>>>>
>>> Not the same thing. You're using the bounds of the slice index.
>>> I was refering to the bounds of the range() function.
>>>
>>>>>> for a in range(9,-9,-1):print(a,end=' ')
>>>>>>
>>> 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8
>>>
>>> To get that to stop at 0, you use a -1 as the bounds:
>>>
>>>>>> for a in range(9,-1,-1):print(a,end=' ')
>>>>>>
>>> 9 8 7 6 5 4 3 2 1 0
>>>
>>> Your slice notation only works if the last (first?) number in
>>> the range happens to be 0. What if the range bounds were variables?
>>> You may still want to force the range's last number to be 0 by
>>> using a constant like range(a,-1,-1) rather than just take
>>> the last number of range(a,b,-1) by using slice notation.
>>>
>> All true and valid of course, but I was just contridicting the "the
>> ONLY way to get a 0" (emphasis mine) part of the statement.
>>
>
> Does it still contradict if you do not use the '::' as the OP
> requested?
>

Not to my knowledge... I believe your statement is true in all cases
which explicitly state the stop value.

0 new messages