On 30 Oct 2013 07:26, "Ron Adam" <ron3200@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
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
now it 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@python.org https://mail.python.org/mailman/listinfo/python-ideas