[Numpy-discussion] Backwards slicing including the first element

josef.pktd at gmail.com josef.pktd at gmail.com
Wed Mar 10 10:56:31 EST 2010


On Wed, Mar 10, 2010 at 10:19 AM, Warren Weckesser
<warren.weckesser at enthought.com> wrote:
> Warren Weckesser wrote:
>> Jerome Esteve wrote:
>>
>>> Dear all,
>>>
>>> Is there a way to give an integer value to j when using a[i:j:-1] so
>>> that the first element of the array can be included in the slice ?
>>>
>>> I would like to use some code like a[i:i-k:-1] to get a slice of
>>> length k.
>>>
>>> The numpy documentation seems to suggest that j=-1 should work:
>>>
>>> "Assume n is the number of elements in the dimension being sliced.
>>> Then, if i is not given it defaults to 0 for k > 0 and n for k < 0 .
>>> If j is not given it defaults to n for k > 0 and -1 for k < 0 .
>>> If k is not given it defaults to 1."
>>>
>>> But a[i:i-k:-1] is empty if i-k is -1. The workaround is a[i::-1][:k],
>>> is there something simpler ?
>>>
>>
>> You could use a[i:i-(len(a)+k):-1].  This works because a[-len(a)] is
>> the same as a[0].
>>
>>
>
> I'm going to be pedantic and amend that last sentence.  While it is true
> the a[-len(a)] is the same as a[0], that is not why this works.  A
> better explanation is that Python is lenient about handling the value
> given as the end position in a slice.  It does not have to be a valid
> index.  If the value is out of range, Python will include everything up
> to the end of the actual data, and it will not raise an error.  So you
> can do slices like the following:
> -----
> In [101]: w
> Out[101]: [10, 11, 12, 13, 14]
>
> In [102]: w[2:-5:-1]
> Out[102]: [12, 11]
>
> In [103]: w[2:-6:-1]
> Out[103]: [12, 11, 10]
>
> In [104]: w[2:-7:-1]
> Out[104]: [12, 11, 10]
> -----
> Note that -6 and -7 are not valid indices; using w[-6]  will raise an
> IndexError.
>
>
> Warren
>
>
>> For example:
>>
>> -----
>> In [57]: a
>> Out[57]: array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>
>> In [58]: i = 3
>>
>> In [59]: for k in range(5):
>>    ....:     print k, a[i:i-(len(a)+k):-1]
>>    ....:
>>    ....:
>> 0 []
>> 1 [13]
>> 2 [13 12]
>> 3 [13 12 11]
>> 4 [13 12 11 10]
>>
>> -----

I thought, I had also used the -1 before, but it only works with range, e.g.

>>> [(i,i-k,np.arange(5)[range(i,i-k,-1)]) for i in range(1,5)]
[(1, -1, array([1, 0])), (2, 0, array([2, 1])), (3, 1, array([3, 2])),
(4, 2, array([4, 3]))]

the "or None" trick is more complicated when counting down

>>> [(i,i-k,np.arange(5)[i:(i-k if (i-k!=-1) else None):-1]) for i in range(1,5)]
[(1, -1, array([1, 0])), (2, 0, array([2, 1])), (3, 1, array([3, 2])),
(4, 2, array([4, 3]))]

I will mark Warrens solution as something to remember.

Josef


>>
>> Warren
>>
>>
>>> Many thanks in advance, Jerome.
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> NumPy-Discussion mailing list
>>> NumPy-Discussion at scipy.org
>>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>>>
>>>
>>
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion at scipy.org
>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>



More information about the NumPy-Discussion mailing list