[Tutor] What exactly is [::-1]?
Chris Calloway
cbc at unc.edu
Thu Jul 26 21:37:54 CEST 2007
Kent Johnson wrote:
> AFAIK extended slicing is not supported by any standard Python data
> types, it was added specifically for Numeric.
Numeric *is* responsible for getting *one* of the two forms of extended
slicing added (the one with multiple slices or ellipses separated by
commas) and yes, that *one form* isn't supported by any builtin or
"standard" global module Python data types.
The *other* form of extended slicing, the one with two colons (and no
commas) is supported by typeseq objects, though.
The phrase "extended slicing" probably ought to be clarified in the
documentation as having two distinct forms (stepped and multiple). This
is a root of considerable confusion for people reading about extended
slicing in the standard documentation.
Extended slicing is really talking about two ways of creating a *slice
object* (and there are other ways of creating slice objects). And not
all slice objects are created equally as far as typeseq and array module
objects are concerned.
A sensible solution would be to refer to the stepped form as a simple
slice and realize that both "stepped simple" slices and comma-extended
slices create slice objects in Python 2.3 and later. I don't know how
wise it would be to further confuse the issue by changing the
documentation at this point. It's a judgment call.
Using stepped slicing with numpy/Numeric/numarray style arrays is also
very different from using it with the standard array module and typeseq
objects.
With typeseq objects, the two colon extended slicing provides a reversed
*copy* of the typeseq object as opposed to the .reverse method which
reverses a typeseq object *in place* (and has no return value):
>>> a = [0,1,2,3,4]
>>> b = a[::-1]
>>> a[2] = 6
>>> a.reverse()
>>> a
[4, 3, 6, 1, 0]
>>> b
[4, 3, 2, 1, 0]
>>>
Same with the array module (a copy is made):
>>> import array
>>> e = array.array('i',[0,1,2,3,4])
>>> f = e[::-1]
>>> e[2] = 23
>>> e.reverse()
>>> e
array('i', [4, 3, 23, 1, 0])
>>> f
array('i', [4, 3, 2, 1, 0])
>>>
However, with numpy/Numeric/numarray style arrays, extended slicing
gives you a "view" of the original array, somewhat similar to using
.reverse() on typeseq objects (but still different because the original
array is unchanged). Changes to the original array will be *reflected*
in the view objects of that original array (unlike in the example copied
objects above):
>>> import numpy
>>> c = numpy.array([0, 1, 2, 3, 4])
>>> d = c[::-1]
>>> c[2] = 9
>>> c
array([0, 1, 9, 3, 4])
>>> d
array([4, 3, 9, 1, 0])
>>>
To get a reversed *copy* of numpy/Numeric/numarray style arrays, you'll
need to use their .copy() method on the extended slice.
numpy/Numeric/numarray style arrays have no .reverse() method as typeseq
and array module objects do:
>>> g = c[::-1].copy()
>>> c[2] = 42
>>> c
array([ 0, 1, 42, 3, 4])
>>> g
array([4, 3, 9, 1, 0])
>>> c.reverse()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'numpy.ndarray' object has no attribute 'reverse'
>>>
So that extended slicing of the form [::-1] is kind of necessary with
numpy/Numeric/numarray style arrays in order to "reverse" the object.
Just remember, double colon extended slicing has a different effect on
typeseq and array module objects (by making a copy).
--
Sincerely,
Chris Calloway
http://www.seacoos.org
office: 332 Chapman Hall phone: (919) 962-4323
mail: Campus Box #3300, UNC-CH, Chapel Hill, NC 27599
More information about the Tutor
mailing list