[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