[Python-3000] Future of slices

Josiah Carlson jcarlson at uci.edu
Mon May 1 10:32:23 CEST 2006

If you want to get my general opinion; -1 on all of your recommendations. 
In each part, I describe why.

Alexander Belopolsky <alexander.belopolsky at gmail.com> wrote:
> 1. l[:] syntax for shallow copy.

Note that [:] doesn't necessarily copy.  It certainly is the case for
Python lists, strings, tuples, and unicode today, but given standard
slicing of l[i:j] producing a copy of a section of a list/string/tuple
from i...j, removing the first is equivalent to 'the start', and
removing the second being equivalent to 'the end'; having l[:] do
something other than slicing the entire sequence (at least for
list/string/tuple) seems pretty unintuitive.

> 2. Overloading of [] syntax. The primary meaning of c[i] is: get the  
> i-th item from the collection.
> The main problem with [] overloading is that c[i] is not  
> guaranteed to be "smaller" than c.

How is this related at all to anything?

> This problem is even worse for strings, where c[i] is  
> *always* a slice: c[i] is the same as c[i:i+1].

    >>> ''[0]
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    IndexError: string index out of range
    >>> ''[0:1]

> maybe we can reconsider compiling l[a:b:c] into  
> l.__getitem__(slice(a,b,c)) and go back to __getslice__.

You can still use __getslice__ if you want (I believe it is deprecated,
but I don't know when it will be removed)...

    >>> class foo(object):
    ...     def __getitem__(self, *args):
    ...             print 'getitem', args
    ...     def __getslice__(self, *args):
    ...             print 'getslice', args
    >>> foo()[1]
    getitem (1,)
    >>> foo()[1:]
    getslice (1, 2147483647)
    >>> del foo.__getslice__
    >>> foo()[1:]
    getitem (slice(1, None, None),)

> 3.  Overloading of []= syntax. Similarly to #2, this is the case when  
> the same notation is used to do conceptually different operations.   
> In addition it provides alternative ways to do the same thing (e.g. l  
> += a vs. l[len(l):] = a).

There should be one-- and preferably only one --obvious way to do it.

'l[len(l):] = a' is not obvious.  In my opinion, neither is 'l += a' (at
least for certain kinds of 'l' and 'a'). If you have a list,
list.extend() is the obvious way. If you have something else, then
probably some other method is the obvious way. Getting rid of
non-obvious ways of doing these kinds of things would be foolish,
especially when it would be disabling corner cases that may be used by
real code (and not interactive sessions).

Say, for example, someone were doing something like...
    l[i:] = k
And what if i just happened to be >= len(l)?  How would raising an
exception help anyone?

> 4. Extended slicing.  I believe the most common use case l[::-1] was  
> eliminated with the introduction of "reversed". The remaining  
> functionality in case of a tuple c can be expressed as tuple(c[i] for  
> i in range(start,stop, stride)).  The later is more verbose than c 
> [start:stop:stride], but also more flexible.

Technically speaking, all slicing for current built-in Python sequence
objects can be replaced by a variant of:
    <type>(c[i] for i in xrange(start,stop,step))
...but that doesn't mean that removing read-based slicing makes any
sense at all.  Which would you rather do:
    b = a[i:j]
    b = str(a[k] for i in xrange(i,j))

Obviously the first.  People who use extended slicing feel the same way,
as they can add a :X and have precisely what they want.

 - Josiah

More information about the Python-3000 mailing list