Possible improvement to slice opperations.

Ron Adam rrr at ronadam.com
Mon Sep 5 11:35:24 EDT 2005


Magnus Lycka wrote:

> Ron Adam wrote:
> 
>> Slicing is one of the best features of Python in my opinion, but
>> when you try to use negative index's and or negative step increments
>> it can be tricky and lead to unexpected results.
> 
> 
> Hm... Just as with positive indexes, you just need to understand
> the concept properly.
> 
>> This topic has come up fairly often on comp.lang.python, and often 
>> times, the responses include:
>>
>>     * Beginners should avoid negative extended slices.
>>
>>     * Slices with negative step increments are for advanced
>>       python programmers.
> 
> 
> I certainly wouldn't respond like that...
> 
>>     * It's not broke if you look at it in a different way.
>>
>>     * You should do it a different way.
> 
> 
> Those are correct, but need to be complemented with helpful
> explanations. It's often like this, that we think things seem
> strange, because we don't see it right. We need a new perspective.
> For instance, it took me a long time to understand OOP, but once
> the concept was clear, things fell into place. Often, we fail to
> see things due to preconceptions that mislead us. Like Yoda said:
> "You need to unlearn what you have learnt."

To me, seeing a lot responses of this sort is an indicator it needs to 
be simplified/or that something isn't right about them.  They shouldn't 
be that difficult to use or explain.

>>     - Extended slices with negative values return values that
>>       have less items than currently.
>>
>>     - Slices with negative step values return entirely different
>>       results.
> 
> 
> Over my dead body! ;) Honestly, I can't imagine you'll get agreement
> over such a change.

Yet, your description of how it works below is closer to what I'm 
proposing than how they currently work.


>> REVERSE ORDER STEPPING
>> ----------------------
>> When negative steps are used, a slice operation
>> does the following.  (or the equivalent)
>>
>>    1. reverse the list
>>    2. cut the reversed sequence using start and stop
>>    3. iterate forward using the absolute value of step.
> 
> 
> I think you are looking at this from the wrong perspective.
> 
> Whatever sign c has:
> For s[a:b:c], a is the index for the first item to include,
> b is the item after the last to include (just like .end() in
> C++ iterators for instance), and c describes the step size.

Yes, and that is how it "should" work.  But....

With current slicing and a negative step...

[   1   2   3   4   5   6   7   8   9  ]
  -9  -8  -7  -6  -5  -4  -3  -2  -1  -0

r[-3:]  ->  [7, 8, 9]    # as expected
r[-3::-1] ->  [7, 6, 5, 4, 3, 2, 1, 0]   # surprise

The seven is include in both cases, so it's not a true inverse selection 
either.

In most cases, negative step (or stride) values are used
to reverse the whole lists, so this issue doesn't come up.



> To get a non-empty result, you obviously must have a > b iff
> c < 0.
> 
> a defaults to 0, b defaults to None (which represents the
> item beyond the end of the sequence) and c defaults to 1.
> 
> This is basically all you need to understand before you use
> a or b < 0. There are no special cases or exceptions.

See above. ;-)


> The concept of negative indices are completely orthogonal
> to the concept of slicing today. You can learn and
> understand them independently, and will automatically
> be able to understand how to use the concepts together,
> iff you actually understood both concepts correctly.

It's easy to think you understand something when you don't. I spend 
quite a while figuring this out, And am sure about how it works. If 
there are issues with this, then it will probably be in how I describe 
it, what words or terminology is used, and weather or not it's the 
proper approach.

There are actually two distinct proposals here, not just one.

     1. Fixing negative strides so they return the slice indexed as you 
say they should.

     2. Using base one negative index's and picking item from the right 
of negative index's instead of the right.


They don't both need to implemented, Item 1 could be fixed in 2.5.

Cheers,
Ron



More information about the Python-list mailing list