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

Nick Coghlan ncoghlan at gmail.com
Tue Oct 29 23:07:00 CET 2013


On 30 Oct 2013 07:26, "Ron Adam" <ron3200 at gmail.com> wrote:
>
>
>
> On 10/29/2013 03:19 PM, MRAB wrote:
>>
>> On 29/10/2013 17:49, Ron Adam wrote:
>>>
>>> On 10/28/2013 10:43 PM, MRAB wrote:
>>>>>
>>>>> I think a reverse index object could be easier to understand.  For
now it
>>>>> could be just a subclass of int.  Then 0 and rx(0) would be
>>>>> distinguishable
>>>>> from each other.  (-i and rx(i) would be too.)
>>>>>
>>>>>       seq[0:rx(0)]        Default slice.
>>>>>       seq[0:rx(0):-1]     Reversed slice.  (compare to above)
>>>>>
>>>>>       seq[rx(5): rx(0)]   The last 5 items.
>>>>>
>>>>>
>>>>> A syntax could be added later.  (Insert preferred syntax below.)
>>>>>
>>>>>       seq[\5:\0]           The last 5 items
>>>>>
>>>> If you're going to have a reverse index object, shouldn't you also have
>>>> an index object?
>>>>
>>>> I don't like the idea of counting from one end with one type and from
>>>> the other end with another type.
>>>
>>>
>>> It would be possible to make it work both ways by having a direction
>>> attribute on it which is set with a unary minus opperation.
>>>
>>>        seq[-ix(5): -ix(0)]
>>>
>>> Positive integers would work normally too.  Negative ints would just be
to
>>> the left of the first item rather than the left of the last item.
>>>
>>>
>>>
>>> Just had a thought.  In accounting negative numbers are often
represented
>>> as a positive number in parenthes.
>>>
>>>          seq[(5,):(0,)]        Last 5 items.
>>>
>>> Unfortunately we need the comma to define a single item tuple.  :-/
>>>
>>> But this wuold work without adding new syntax or a new type.  And the
','
>>> isn't that big of a deal.  It would just take a bit of getting used to
it.
>>>
>>>
>>>> But if you're really set on having different types of some kind, how
about
>>>> real counting from the left and imaginary counting from the right:
>>>>
>>>>      seq[5j : 0j] # The last 5 items
>>>>
>>>>      seq[1 : 1j] # From second to second-from-last
>>>>
>> [snip]
>> Suppose there were two new classes, "index" and "rindex". "index"
>> counts from the left and "rindex" counts from the right.
>>
>> You could also use unary ">" and "<":
>>
>>      >x == index(x)
>>      <x == rindex(x)
>>
>> Slicing would be like this:
>>
>>      seq[<5 : <0] # The last five items
>>      seq[>1 : <1] # From the second to the second-from-last.
>>
>> Strictly speaking, str.find and str.index should also return an index
>> instance. In the case of str.find, if the string wasn't found it would
>> return >-1 (i.e. index(-1)), which, when used as an index, would raise
>> an IndexError (index(-1) isn't the same as -1).
>>
>> In fact, index or rindex instances could end up spreading throughout
>> the language, to wherever an int is actually an index. (You'd also have
>> to handle addition and subtraction with indexes, e.g. pos + 1.)
>>
>> All of which, I suspect, is taking it too far! :-)
>
>
> I think it may be the only way to get a clean model of slicing from both
directions with a 0 based index system.

Isn't all that is needed to prevent the default wraparound behaviour
clamping negative numbers to zero on input?

As in:

def clampleft(start, stop, step):
    if start is not None and start < 0:
        start = 0
    if stop is not None and stop < 0:
        stop = 0
    return slice(start, stop, step)

Similar to rslice and "reverse=False", this could be implemented as a
"range=False" flag (the rationale for the flag name is that in "range",
negative numbers are just negative numbers, without the wraparound
behaviour normally exhibited by the indices calculation in slice objects).

I think there are two reasonable options that could conceivably be included
in 3.4 at this late stage:

* Make slice subclassable and ensure the C API and stdlib respect an
overridden indices() method

* add a "reverse" flag to both slice and range, and a "range" flag to slice.

Either way, if any changes are going to be made, a PEP should be written up
summarising some of the ideas in this thread, including the clampleft() and
rslice() recipes that work in current versions of Python.

Cheers,
Nick.

>
> Cheers,
>    Ron
>
>
>
>
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131030/633e352c/attachment.html>


More information about the Python-ideas mailing list