Negative array indicies and slice()
robert.kern at gmail.com
Fri Nov 2 11:48:50 CET 2012
On 11/2/12 8:57 AM, Andrew Robinson wrote:
> Hi Ian,
> I apologize for trying your patience with the badly written code example. All
> objects were meant to be ThirdParty(), the demo was only to show how a slice()
> filter could have been applied for the reasons PEP357 made index() to exist.
> eg: because numpy items passed to __getitems__ via slice syntax [::] were
> illegal values.
> PEP 357 is the one who specifically mentioned Numpy types -- which is the only
> reason I used the name in the example; I could have just as well used a string.
> I am fully aware of what numpy does -- I have used it; modified the fortran
> interfaces underneath, etc.
> The index() method, however, affects *all* list objects in Python, not just
> Numpy's -- correct?
Please forget that PEP 357 mentions slices at all. The motivation for the
__index__() method (not index()) goes far beyond slices. I'm not really sure why
they are given such a prominent place in the PEP. Let me try to lay out the
motivation more clearly.
numpy has objects that represent integers but cannot be subclasses of the Python
int or long objects because their internal representations are different. These
are the width-specific types: uint8, int16, int64, etc. Before __index__() was
introduced, all indexing operations in the builtin Python sequence types
strictly checked for int or long objects and rejected other objects. We wanted
to provide a generic method that third party types could implement to say, "Yes,
I really am an integer, here is my value in a canonical representation you can
understand." We could not use __int__() for this purpose because it has
additional semantics, namely conversion from not-integers to integers. This is
why floats are mentioned; they do not generally represent integers but they do
define an __int__() method for their conversion to ints via the floor()
function. Generally, they should be rejected as indices. With the __index__()
method, we have a solution: int16 and the rest get __index__() methods and float
This is used where an integer index or offset is needed, not just in slices.
List indices, file.seek(), mmap.mmap(), etc. The change to use PyIndex_Check()
instead of PyInt_Check() was not very difficult or extensive. Even if you were
to change the slicing API for your other reasons, __index__() would still be needed.
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-list