[C++-sig] Re: New slice implementation

Raoul Gough RaoulGough at yahoo.co.uk
Fri Jan 9 14:19:01 CET 2004


Jonathan Brandmeyer <jbrandmeyer at earthlink.net> writes:

> On Thu, 2004-01-08 at 20:55, Raoul Gough wrote:
[snip]
>> part = v[1::4]
>> 
>> calls v.__getitem__ with a PySliceObject (1, None, 4)
>
> *I* won't end up with a PySliceObject created by the Python interpreter,
> I will end up with a boost::python::slice object manager that has been
> automatically converted by def() and/or class_::def() from the original
> PySliceObject.

Well, that's the bit I don't understand. How do you create a
boost::python::slice object from a PySliceObject without a suitable
constructor? Unless you're just not interested in covering this case.

[snip]
>> I don't try to support slices unless the container has random access
>> (and then there's no need for a reverse iterator).
>
> Why not?  There is no reason whatsoever not to support every container
> with bidirectional iterators.  You can even slice on maps if you want
> to, although such a thing has been forbidden for python dict's.

Sure it's possible. I didn't see much need to do it though. For
instance, if you have a C++ std::list exposed to Python, do you really
want to be able to do:

>>> cxx_list[87]

or

>>> cxx_list[20:80:4]

Maybe you do, but I think you would probably be better off with
std::vector.

>
>> >
>> >> >
>> >> > # I think this should raise IndexError; crashes.
>> >> > foo[-1:0] = [7, 8, 9]
>> >> 
>> >> With a real python list, it inserts 7, 8, 9 before the last element:
>> >> 
>> >> >>> v = [1,2,3,4]
>> >> >>> v[-1:0] = [7,8,9]
>> >> >>> print v
>> >> [1, 2, 3, 7, 8, 9, 4]
>> >
>> > Yes, that is what happens: performing an insertion before the provided
>> > start value.  However, I think that it should be an undefined operation
>> > since the expression is utter nonsense.  I've looked at the source code
>> > for PyListObject, and I think that this behavior is the result of bounds
>> > limiting rather than real error checking.
>> 
>> I don't understand this. Assigning something into an empty slice in a
>> container always performs an insertion. More generally, assigning a
>> longer list to a plain slice with fewer elements performs insertion.
>> e.g.
>
> No, assigning any sequence to a slice by calling 
> object.__setslice__(slice, sequence) replaces the old slice with the
> values of the new slice IF the slice uses either -1 or 1 (either
> implicitly or explicitly) for its step size.  If the step size is
> non-singular, then the sizes of the slice and the sequence must be
> identical.

The lack of a step size is what I was getting at with "plain slice". I
guess I should have been more precise.

>
>> >>> l = [1,2,3,4]
>> >>> l[3:0] = [7,8,9]
>
> Think about what this expression means: Starting at the fourth element
> inclusive, and ending at the first element, exclusive with an increment
> of forward 1, delete elements and replace them with the elements of the
> list [7,8,9].  That's like starting off by calling
> std::list::delete(start, stop) with a 'stop' iterator that is not
> reachable from 'start'!

But that's not the way *Python* does things. Are you saying that
lst[3:0] should just crash the interpreter? That's what a C++
algorithm would probably do with that kind of input.

>
> The issue isn't that you are performing an insertion after a
> well-defined point in the sequence, it is that you are performing a
> replacement of an undefined section of the sequence.

I would argue that the section of the sequence *is* well defined.

>
>> I haven't used Numeric before - is it documented somewhere?
>
> See numpy.sourceforge.net and in Debian the python2.2-numeric,
> python2.3-numeric, and python-numeric-tutorial packages.

>From what I can see, the arrays can't change in length, so obviously
they don't support insertion, or replacing a shorter slice with a
longer sequence.

>
>> >
>> > See Python bug# 873305 at http://sourceforge.net/tracker/?group_id=5470
>> 
>> I don't see any place to enter the bug number - how do I get to see
>> bug 873305?
>
> Sorry, that was my fault.  Try this one:
> http://sourceforge.net/tracker/index.php?func=detail&aid=873305&group_id=5470&atid=305470
>

I don't think I agree with what you're saying here. Would you agree
that __getitem__ from e.g. lst[4:2] should be an empty sequence?

Quoting from http://www.python.org/doc/current/lib/typesseq.html

"(4) [...] If i is greater than or equal to j, the slice is empty."

I think that's pretty clear for __getitem__. So now the question is,
what is the result of replacing an empty slice in a container with a
non-empty sequence? If the container supports insertion, inserting the
sequence seems logical enough to me.

-- 
Raoul Gough.
export LESS='-X'





More information about the Cplusplus-sig mailing list