Negative array indicies and slice()

Ethan Furman ethan at stoneleaf.us
Thu Nov 1 15:12:15 CET 2012


Andrew Robinson wrote:
>   On 10/31/2012 02:20 PM, Ian Kelly wrote:
>> On Wed, Oct 31, 2012 at 7:42 AM, Andrew Robinson  wrote:
>>> Then; I'd note:  The non-goofy purpose of slice is to hold three
>>> data values;  They are either numbers or None.  These *normally*
>>> encountered values can't create a memory loop.
>>> So, FOR AS LONG, as the object representing slice does not contain
>>> an explicit GC pair; I move that we mandate (yes, in the current
>>> python implementation, even as a *fix*) that its named members may
>>> not be assigned any objects other than None or numbers....
>>>
>>> eg: Lists would be forbidden....
>>>
>>> Since functions, and subclasses, can be test evaluated by int(
>>> the_thing_to_try ) and *[] can too,
>>> generality need not be lost for generating nothing or numbers.
>>
>>
>> PEP 357 requires that anything implementing the __index__ special 
>> method be allowed for slicing sequences (and also that __index__ be 
>> used for the conversion).  For the most part, that includes ints and 
>> numpy integer types, but other code could be doing esoteric things 
>> with it.
> 
> I missed something... (but then that's why we're still talking about it...)
> 
> Reading the PEP, it notes that *only* integers (or longs) are permitted 
> in slice syntax.

Keep in mind that PEPs represent Python /at that time/ -- as Python
moves forward, PEPs are not updated (this has gotten me a couple times).


>> The change would be backward-incompatible in any case, since there is 
>> certainly code out there that uses non-numeric slices -- one example 
>> has already been given in this thread.
> 
> Hmmm.....
> 
> Now, I'm thinking -- The purpose of index(), specifically, is to notify 
> when something which is not an integer may be used as an index;  You've 
> helpfully noted that index() also *converts* those objects into numbers.
> 
> Ethan Fullman mentioned that he used the names of fields, "instead of 
> having to remember the _offsets_"; Which means that his values _do 
> convert_ to offset numbers

Furman, actually.  :)

And my values do *not* convert to indices (at least, not automatically).
My __getitem__ code looks like:

     elif isinstance(item, slice):
         sequence = []
         if isinstance(item.start, (str, unicode)) \
         or isinstance(item.stop, (str, unicode)):
             field_names = dbf.field_names(self)
             start, stop, step = item.start, item.stop, item.step
             if start not in field_names or stop not in field_names:
                 raise MissingFieldError(
                     "Either %r or %r (or both) are not valid field names"
                     % (start, stop))
             if step is not None and not isinstance(step, (int, long)):
                 raise DbfError(
                     "step value must be an int or long, not %r"
                     % type(step))
             start = field_names.index(start)
             stop = field_names.index(stop) + 1
             item = slice(start, stop, step)
         for index in self._meta.fields[item]:
             sequence.append(self[index])
         return sequence

In other words, the slice contains the strings, and my code calculates
the offsets -- Python doesn't do it for me.


> His example was actually given in slice syntax notation [::].
> Hence, his objects must have an index() method, correct?.

Nope.

~Ethan~


More information about the Python-list mailing list