[Python-ideas] improvements to slicing (original) (raw)
Ron Adam rrr at ronadam.com
Wed Oct 6 21:21:03 CEST 2010
- Previous message: [Python-ideas] Inclusive Range
- Next message: [Python-ideas] improvements to slicing
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 10/06/2010 08:58 AM, Nick Coghlan wrote:
If I was going to ask for a change to anything in Python's indexing semantics, it would be for negative step values to create ranges that were half-open at the beginning rather than the end, such that reversing a slice just involved swapping the start value with the stop value and negating the step value.
Yes, negative slices are very tricky to get right. They could use some attention I think.
As it is, you also have to subtract one from both the start and stop value to get the original range of values back. However, just like the idea of ranges starting from 1 rather than 0, the idea of negative slices giving ranges half-open at the start rather than the end is also doomed by significant problems with backwards compatibility. For a new language, you might be able to make the argument that the alternative behaviour is a better design choice. For an existing one like Python, any possible benefits are so nebulous as to not be worth the inevitable hassle involved in changing the semantics)
We don't need to change the current range function/generator to add inclusive or closed ranges. Just add a closed_range() function to the itertools or math module.
[n for n in closed_range(-5, 5, 2)] --> [-5, -3, -1, 1, 3, 5]
I just noticed the getslice method is no longer on sequences. (?)
My preference is for slicing to be based more on practical terms for manipulating sequences rather than be defined in a purely mathematical way.
Have the direction determine by the start and stop values rather than than by the step value so that the following is true.
"abcdefg"[start:stop:step] == "abcdefg"[start:stop][::step]
Reversing the slice can be done by simply swapping the start and stop.
Negating the slice too would give you ...
"abcdefg"[start:stop:step] == "abcdefg"[stop:start:-step]
Negating the step would not always give you the reverse sequence for steps larger than 1, because the result may not contain the same values.
'abcd'[::2] 'ac' 'abcd'[::-2] 'db'
This is the current behavior and wouldn't change.
A positive step value would step from the left, and a negative step value would step from the right of the slice determined by start and stop. This already works if you don't give stop and start values.
"abcdefg"[::2] 'aceg' "abcdefg"[::-2] 'geca'
And these can be used in for loops or list comps.
[c for c in "abcdefg"[::2]] ['a', 'c', 'e', 'g']
If we could add a width value to slices we would be able to do this.
"abcdefg"[::2:2] 'abcdefg'
;-)
As unimpressive as that looked, when used in a for loop or list comp it would give us an easy and useful way to step through data.
[cc for cc in "abcdefg"[::2:2]] --> ['ab', 'cd', 'ef', 'g']
You could also spell that as...
list("abcdefg")[::2:2]) --> ['ab', 'cd', 'ef', 'g']
The problems start when you try to use actual index values to specify start and stop ranges.
You can't index the last element with an explicit stop value.
"abcdefg"[0:-1] 'abcdef'
"abcdefg"[0:-0] ''
But we can use "None" which is awkward and requires testing the stop value when the index is supplied by a variable.
'abcdefg'[:None] 'abcdefg'
I'm not sure how to fix this one. We've been living with this for a long time so it's not like we need to fix it all at once.
Negative indexes can be confusing.
"abcdefg"[-5:5] 'cde' # OK "abcdefg"[5:-5] '' # Expected "edc'" here, not ''. "abcdefg"[5:-5:-1] 'fed' # Expected reverse of '' here, # or 'cde', not 'fed'.
With the suggested change we get...
"abcdefg"[-5:5] 'cde' # Stays the same. "abcdefg"[5:-5] 'edc' # Swapping start and stop reverses it. "abcdefg"[5:-5:-1] 'cde' # Negating the step, reverses it again.
I think these are easier to use than the current behavior. It doesn't change slices using positive indexes and steps so maybe it's not so backward incompatible to sneak in. ;-)
Ron
- Previous message: [Python-ideas] Inclusive Range
- Next message: [Python-ideas] improvements to slicing
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]