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

Terry Reedy tjreedy at udel.edu
Mon Oct 28 22:41:27 CET 2013


On 10/28/2013 4:56 PM, Tim Peters wrote:

> [Bruce Leban]
>> It's definitely not "finally clear" as it's a change in semantics.
>
> Of course it is.
>
>> What about negative strides other than -1?
>
> All strides start the same way, by (conceptually) selecting s[i:j]
> first.  Then the stride is applied to that contiguous slice, starting
> with the first element and taking every abs(k) element thereafter.
> Finally, if k is negative, that sequence is reversed.  k=1, k=-1, k=2,
> k=-2, ..., all the same.

I think this is wrong. Conceptually reverse first, if indicated by 
negative stride, then select: see my previous post for my rationale, and 
below.

>> Which of these is expected?
>>
>> (A) '012345678'[::-2] == '86420'
>>      '0123456789'[::-2] == '97531'

This is the current behavior and I think that [::k] should continue to 
work as it does. I believe Guido only suggested deprecating negative 
strides with non-default endpoints, which implies negative strides 
*with* default endpoints should continue as are. We should not break 
more than necessary.

>> (B) '012345678'[::-2] == '86420'
>>      '0123456789'[::-2] == '86420'

> B.

Aside from all else, I find A) more intuitive. It certainly strikes me 
as more likely to be wanted, though either is obviously rare.

>> If (A) I can get the (B) result by writing [::2][::-1]
 >> but if (B), I'm forced to write:
>>
>> s[0 if len(s) % 2 == 1 else 1::2]
>>
>> or something equally ugly.

No, just reverse the slices.

 >>> '0123456789'[::-1][::2]
'97531'
 >>> '012345678'[::-1][::2]
'86420'

If we were to make the change, I think the docs, at least the tutorial, 
should say that s[i:j:-k] could mean either s[i:j:-1][::k] or 
s[i:j:k][::-1] and that is does mean the former, so if one wants the 
latter, spell it out.

> You're assuming something here you haven't said.  The easiest way to
> get '97531' is to type '97531' ;-)  If your agenda is the general
> "return every 2nd element starting with the last element", then the
> obvious way to do that under the proposal is to write [::-1][::2].
> You can't seriously claim that's harder than the "[::2][::-1]" you
> presented as the obvious way to "get the (B) result" given (A).
>
>> (Also, (A) is the current behavior and switching to (B) would break any
>> existing use of strides < -1.)
>
> Did you notice that Guido titled this thread "Where did we go wrong
> with negative stride?".;-)

I did, and I explained exactly where I thing we went wrong, which was to 
make the interpretation of i and j depend on the sign of k. Undoing this 
does not mandate B instead of A.

-- 
Terry Jan Reedy



More information about the Python-ideas mailing list