[Python-ideas] Where did we go wrong with negative stride?

Guido van Rossum guido at python.org
Sun Oct 27 22:31:49 CET 2013


I wouldn't take out negative strides completely, but I might consider
deprecating lower and upper bounds other than None (== missing). So a[::-1]
would still work, and a[None:None:-1] would be a verbose way of spelling
the same, but a[-1:-6:-1] would be deprecated. Then we could triumphantly
(re-)introduce upper and lower bounds in Python 4, with the meaning
a[i:j:-1] == a[i:j][::-1].


On Sun, Oct 27, 2013 at 2:27 PM, Ryan <rymg19 at gmail.com> wrote:

> Reversing strings and tuples easily. For a string, calling
> ''.join(reversed(mystr)) is just overkill. And tuples aren't quite as
> bad(tuple(reversed(mytuple))), but nonetheless odd.
>
> If you were to take out negative strides, a reverse method should be.added
> to strings and tuples:
>
> 'abcde'.reverse() => 'edcba'
>
>
> Guido van Rossum <guido at python.org> wrote:
>
>> On Sun, Oct 27, 2013 at 10:40 AM, MRAB <python at mrabarnett.plus.com>wrote:
>>
>>> On 27/10/2013 17:04, Guido van Rossum wrote:
>>>
>>>> In the comments of
>>>> http://python-history.**blogspot.com/2013/10/why-**
>>>> python-uses-0-based-indexing.**html<http://python-history.blogspot.com/2013/10/why-python-uses-0-based-indexing.html>
>>>> there were some complaints about the interpretation of the bounds for
>>>> negative strides, and I have to admin it feels wrong. Where did we go
>>>> wrong? For example,
>>>>
>>>> "abcde"[::-1] == "edcba"
>>>>
>>>> as you'd expect, but there is no number you can put as the second bound
>>>> to get the same result:
>>>>
>>>> "abcde"[:1:-1] == "edc"
>>>> "abcde"[:0:-1] == "edcb"
>>>>
>>>> but
>>>>
>>>> "abcde":-1:-1] == ""
>>>>
>>>> I'm guessing it all comes from the semantics I assigned to negative
>>>> stride for range() long ago, unthinkingly combined with the rules for
>>>> negative indices.
>>>>
>>>>  For a positive stride, omitting the second bound is equivalent to
>>> length + 1:
>>>
>>> >>> "abcde"[:6:1]
>>> 'abcde'
>>>
>>
>> Actually, it is equivalent to length; "abcde"[:5:1] == "abcde" too.
>>
>>
>>> For a negative stride, omitting the second bound is equivalent to
>>> -(length + 1):
>>>
>>> >>> "abcde"[:-6:-1]
>>> 'edcba'
>>>
>>
>> Hm, so the idea is that with a negative stride you you should use
>> negative indices. Then at least you get a somewhat useful invariant:
>>
>> if -len(a)-1 <= j <= i <= -1:
>>     len(a[i:j:-1]) == i-j
>>
>> which at least somewhat resembles the invariant for positive indexes and
>> stride:
>>
>> if 0 <= i <= j <= len(a):
>>     len(a[i:j:1]) == j-i
>>
>> For negative indices and stride, we now also get back this nice theorem
>> about adjacent slices:
>>
>> if -len(a)-1 <= i <= -1:
>>     a[:i:-1] + a[i::-1] == a[::-1]
>>
>> Using negative indices also restores the observation that a[i:j:k]
>> produces exactly the items corresponding to the values produced by range(i,
>> j, k).
>>
>> Still, the invariant for negative stride looks less attractive, and the
>> need to use negative indices confuses the matter. Also we end up with -1
>> corresponding to the position at one end and -len(a)-1 corresponding to the
>> position at the other end. The -1 offset feels really wrong here.
>>
>> I wonder if it would have been simpler if we had defined a[i:j:-1] as the
>> reverse of a[i:j]?
>>
>> What are real use cases for negative strides?
>>
>
> --
> Sent from my Android phone with K-9 Mail. Please excuse my brevity.
>



-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131027/1b3b5948/attachment.html>


More information about the Python-ideas mailing list