Thoughts on PEP284

Stephen Horne $$$$$$$$$$$$$$$$$ at $$$$$$$$$$$$$$$$$$$$
Tue Sep 23 18:14:12 CEST 2003

On Tue, 23 Sep 2003 10:22:50 GMT, Alex Martelli <aleax at>

>> Adding operators to types is always problematic because it defeats
>> Pythons's runtime checking. Assuming that integer slicing would be added
>> to Python, methods that would expect a list of integers would suddenly
>> also work with integers. In most cases, they would not work correctly, but
>> you wouldn't get a meaningful exception.
>Careful: in Stephen's proposal, slicing would NOT work on *INTEGERS* --
>rather, it would work on the *INT TYPE ITSELF*, which is a very, very
>different issue.

Exactly - thanks for that.

Actually, Sean Ross posted a prototype implementation which makes a
good point - theres no reason why the sliceable object needs to be the
standard 'int' type in Python as it is now. Maybe a library extended
int type, imported only if used, makes sense. Maybe this is a recipe
or library proposal rather than a language proposal.

>>> Also, one extra feature is that the loop can be infinite (which range
>>> and xrange cannot achieve)...
>>>   for i in int [0:] :
>No way, Jose -- now THAT would break things (in admittedly rare
>cases -- a method expecting a list and NOT providing an upper bound
>in the slicing).  I'd vote for this to be like int[0:sys.maxint+1]
>(i.e., last item returned is sys.maxint).

True - but boundless generators are already in use.

An implicit sys.maxint(ish) upper bound seems wrong to me. I would
either go with allowing the infinite loop or requiring an explicit
upper bound.

>What Stephen's proposal lacks is rigorous specs of what happens for all
>possible slices -- e.g int[0:-3] isn't immediately intuitive, IMHO;-).

You're right in that this was not intended as a full formal proposal.
But lets see what I can do...

To me, it should be possible to create slices for negative ranges as
easily as positive ranges, so the convention of -1 giving the last
item wouldn't apply.

I already had to look at this issue when I wrapped some C++ container
classes for Python recently (unreleased at present due to the need for
further Pythonicising) - the whole point of doing so was that the
containers allow some more power and flexibility compared with the
Python ones. For instance, my set and (dictionary-like) map classes
are conveniently and efficiently sliceable. But how should the slicing

BTW - there is a price for flexibility - I was very surprised at the
relative speed of a dictionary (at least an order of magnitude faster
than my map) though to be fair I haven't done even trivial
optimisation stuff yet. No, these aren't STL containers.

Anyway, back to the point...

I could have treated slices as specifying subscripts (while the data
structure is *not* a sorted array, it does support reasonably
efficient subscripting) but I felt the upper and lower bounds should
be key values rather than subscripts. But when basing the bounds on
keys, a bound of '-1' logically means a bound with the key value of -1
- not the highest subscript value.

The 'step' value is slightly inconsistent in that it had to be a
subscript-like step (stepping over a specific number of items rather
than a specific key range) as the keys don't always have a sensible
way to interpret these steps. But I'm drifting from the point again.

As a 'set of integers' would IMO logically be sliced by key too, '-1'
should just be a key like any other key, giving...

>>> int [-5:0]
[-5, -4, -3, -2, -1]

>>> int [0:-5]

>>> int [0:-5:-1]
[0, -1, -2, -3, -4]

So to me, the slice should be evaluated as follows...

if step is None : default step to 1
if step == 0 : raise IndexError

if start is None :
  either default to zero or raise IndexError, not sure

if stop is None :
  either raise IndexError or...

  if step > 0 :
    default stop to +infinity
  else :
    default stop to -infinity

Obviously that isn't a real implementation ;-)

Steve Horne

steve at ninereeds dot fsnet dot co dot uk

More information about the Python-list mailing list