Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Negative array indicies and slice()

Reply
Thread Tools

Negative array indicies and slice()

 
 
andrewr3mail@gmail.com
Guest
Posts: n/a
 
      10-29-2012
The slice operator does not give any way (I can find!) to take slices from negative to positive indexes, although the range is not empty, nor the expected indexes out of range that I am supplying.

Many programs that I write would require introducing variables and logical statements to correct the problem which is very lengthy and error prone unless there is a simple work around.

I *hate* replicating code every time I need to do this!

I also don't understand why slice() is not equivalent to an iterator, but can replace an integer in __getitem__() whereas xrange() can't.


Here's an example for Linux shell, otherwise remove /bin/env...
{{{#!/bin/env python
a=[1,2,3,4,5,6,7,8,9,10]
print a[-4:3] # I am interested in getting [7,8,9,10,1,2] but I get [].
}}}
 
Reply With Quote
 
 
 
 
Ian Kelly
Guest
Posts: n/a
 
      10-29-2012
On Sun, Oct 28, 2012 at 9:12 PM, <(E-Mail Removed)> wrote:
> The slice operator does not give any way (I can find!) to take slices from negative to positive indexes, although the range is not empty, nor the expected indexes out of range that I am supplying.
>
> Many programs that I write would require introducing variables and logical statements to correct the problem which is very lengthy and error prone unless there is a simple work around.
>
> I *hate* replicating code every time I need to do this!
>
> I also don't understand why slice() is not equivalent to an iterator, but can replace an integer in __getitem__() whereas xrange() can't.
>
>
> Here's an example for Linux shell, otherwise remove /bin/env...
> {{{#!/bin/env python
> a=[1,2,3,4,5,6,7,8,9,10]
> print a[-4:3] # I am interested in getting [7,8,9,10,1,2] but I get [].
> }}}



For a sequence of length 10, "a[-4:3]" is equivalent to "a[6:3]",
which is an empty slice since index 6 is after index 3.

If you want it to wrap around, then take two slices and concatenate
them with "a[-4:] + a[:3]".
 
Reply With Quote
 
 
 
 
MRAB
Guest
Posts: n/a
 
      10-29-2012
On 2012-10-29 03:12, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> The slice operator does not give any way (I can find!) to take slices from negative to positive indexes, although the range is not empty, nor the expected indexes out of range that I am supplying.
>
> Many programs that I write would require introducing variables and logical statements to correct the problem which is very lengthy and error prone unless there is a simple work around.
>
> I *hate* replicating code every time I need to do this!
>
> I also don't understand why slice() is not equivalent to an iterator, but can replace an integer in __getitem__() whereas xrange() can't.
>
>
> Here's an example for Linux shell, otherwise remove /bin/env...
> {{{#!/bin/env python
> a=[1,2,3,4,5,6,7,8,9,10]
> print a[-4:3] # I am interested in getting [7,8,9,10,1,2] but I get [].
> }}}
>

If the stride is positive (if omitted it defaults to 1), the slice is
from the start index to one before the end index, and a negative index
counts from the end.

a[-4:3] is equivalent to a[len(a)-4:3], which is an empty list if
len(a)-4 >= 3.

It doesn't wrap around.

 
Reply With Quote
 
andrewr3mail@gmail.com
Guest
Posts: n/a
 
      10-29-2012
On Sunday, October 28, 2012 8:43:30 PM UTC-7, Ian wrote:
> On Sun, Oct 28, 2012 at 9:12 PM, andrew wrote:
>
> > The slice operator does not give any way (I can find!) to take slices from negative to positive indexes, although the range is not empty, nor the expected indexes out of range that I am supplying.

>
> >

>
> > Many programs that I write would require introducing variables and logical statements to correct the problem which is very lengthy and error prone unless there is a simple work around.

>
> >

>
> > I *hate* replicating code every time I need to do this!

>
> >

>
> > I also don't understand why slice() is not equivalent to an iterator, but can replace an integer in __getitem__() whereas xrange() can't.

>
> >

>
> >

>
> > Here's an example for Linux shell, otherwise remove /bin/env...

>
> > {{{#!/bin/env python

>
> > a=[1,2,3,4,5,6,7,8,9,10]

>
> > print a[-4:3] # I am interested in getting [7,8,9,10,1,2] but I get [].

>
> > }}}

>
>
>
>
>
> For a sequence of length 10, "a[-4:3]" is equivalent to "a[6:3]",
>
> which is an empty slice since index 6 is after index 3.
>
>
>
> If you want it to wrap around, then take two slices and concatenate
>
> them with "a[-4:] + a[:3]".


Hi Ian,
Well, no it really isn't equivalent.
Consider a programmer who writes:
xrange(-4,3) *wants* [-4,-3,-2,-1,0,1,2]

That is the "idea" of a range; for what reason would anyone *EVER* want -4 to +3 to be 6:3???

I do agree that the data held in -4 is equivalent to the data in 6, but the index is not the same.

So: Why does python choose to convert them to positive indexes, and have slice operate differently than xrange -- for the slice() object can't possibly know the size of the array when it is passed in to __getitem__; They are totally separate classes.

I realize I can concat. two slice ranges, BUT, the ranges do not always span from negative to positive.

eg: a line in my program reads:
a[x-5]

if x is 7, then this is a positive index to a positive index.
So, there is no logic to using two slices concatd !

I use this arbitrary range code *often* so I need a general purpose solution.
I looked up slice() but the help is of no use, I don't even know how I might overload it to embed some logic to concatenate ranges of data; nor even if it is possible.

 
Reply With Quote
 
andrewr3mail@gmail.com
Guest
Posts: n/a
 
      10-29-2012
On Sunday, October 28, 2012 8:43:30 PM UTC-7, Ian wrote:
> On Sun, Oct 28, 2012 at 9:12 PM, andrew wrote:
>
> > The slice operator does not give any way (I can find!) to take slices from negative to positive indexes, although the range is not empty, nor the expected indexes out of range that I am supplying.

>
> >

>
> > Many programs that I write would require introducing variables and logical statements to correct the problem which is very lengthy and error prone unless there is a simple work around.

>
> >

>
> > I *hate* replicating code every time I need to do this!

>
> >

>
> > I also don't understand why slice() is not equivalent to an iterator, but can replace an integer in __getitem__() whereas xrange() can't.

>
> >

>
> >

>
> > Here's an example for Linux shell, otherwise remove /bin/env...

>
> > {{{#!/bin/env python

>
> > a=[1,2,3,4,5,6,7,8,9,10]

>
> > print a[-4:3] # I am interested in getting [7,8,9,10,1,2] but I get [].

>
> > }}}

>
>
>
>
>
> For a sequence of length 10, "a[-4:3]" is equivalent to "a[6:3]",
>
> which is an empty slice since index 6 is after index 3.
>
>
>
> If you want it to wrap around, then take two slices and concatenate
>
> them with "a[-4:] + a[:3]".


Hi Ian,
Well, no it really isn't equivalent.
Consider a programmer who writes:
xrange(-4,3) *wants* [-4,-3,-2,-1,0,1,2]

That is the "idea" of a range; for what reason would anyone *EVER* want -4 to +3 to be 6:3???

I do agree that the data held in -4 is equivalent to the data in 6, but the index is not the same.

So: Why does python choose to convert them to positive indexes, and have slice operate differently than xrange -- for the slice() object can't possibly know the size of the array when it is passed in to __getitem__; They are totally separate classes.

I realize I can concat. two slice ranges, BUT, the ranges do not always span from negative to positive.

eg: a line in my program reads:
a[x-5]

if x is 7, then this is a positive index to a positive index.
So, there is no logic to using two slices concatd !

I use this arbitrary range code *often* so I need a general purpose solution.
I looked up slice() but the help is of no use, I don't even know how I might overload it to embed some logic to concatenate ranges of data; nor even if it is possible.

 
Reply With Quote
 
Andrew
Guest
Posts: n/a
 
      10-29-2012
On Sunday, October 28, 2012 8:43:30 PM UTC-7, Ian wrote:
> On Sun, Oct 28, 2012 at 9:12 PM, <Andrew> wrote:
>
> > The slice operator does not give any way (I can find!) to take slices from negative to positive indexes, although the range is not empty, nor the expected indexes out of range that I am supplying.

>
> >

>
> > Many programs that I write would require introducing variables and logical statements to correct the problem which is very lengthy and error prone unless there is a simple work around.

>
> >

>
> > I *hate* replicating code every time I need to do this!

>
> >

>
> > I also don't understand why slice() is not equivalent to an iterator, but can replace an integer in __getitem__() whereas xrange() can't.

>
> >

>
> >

>
> > Here's an example for Linux shell, otherwise remove /bin/env...

>
> > {{{#!/bin/env python

>
> > a=[1,2,3,4,5,6,7,8,9,10]

>
> > print a[-4:3] # I am interested in getting [7,8,9,10,1,2] but I get [].

>
> > }}}

>
>
>
>
>
> For a sequence of length 10, "a[-4:3]" is equivalent to "a[6:3]",
>
> which is an empty slice since index 6 is after index 3.
>
>
>
> If you want it to wrap around, then take two slices and concatenate
>
> them with "a[-4:] + a[:3]".


Hi Ian,
Well, no it really isn't equivalent; although Python implements it as equivalent.

Consider a programmer who writes:
xrange(-4,3)

They clearly *want* [-4,-3,-2,-1,0,1,2]

That is the "idea" of a range; So, for what reason would anyone want -4 to +3 to be 6:3??? Can you show me some code where this is desirable??

I do agree that the data held in -4 is equivalent to the data in 6, but the index is not the same.

So: Why does python choose to convert them to positive indexes, and have slice operate differently than xrange -- for the slice() object can't possibly know the size of the array when it is passed in to __getitem__; They are totally separate classes.

I realize I can concat. two slice ranges, BUT, the ranges do not always span from negative to positive.

eg: a line in my program reads:
a[x-5]

if x is 7, then this is a positive index to a positive index.
So, there is no logic to using two slices concatd !

I use this arbitrary range code *often* so I need a general purpose solution.
I looked up slice() but the help is of no use, I don't even know how I might overload it to embed some logic to concatenate ranges of data; nor even if it is possible.
 
Reply With Quote
 
Andrew
Guest
Posts: n/a
 
      10-29-2012
On Sunday, October 28, 2012 8:43:30 PM UTC-7, Ian wrote:
> On Sun, Oct 28, 2012 at 9:12 PM, <Andrew> wrote:
>
> > The slice operator does not give any way (I can find!) to take slices from negative to positive indexes, although the range is not empty, nor the expected indexes out of range that I am supplying.

>
> >

>
> > Many programs that I write would require introducing variables and logical statements to correct the problem which is very lengthy and error prone unless there is a simple work around.

>
> >

>
> > I *hate* replicating code every time I need to do this!

>
> >

>
> > I also don't understand why slice() is not equivalent to an iterator, but can replace an integer in __getitem__() whereas xrange() can't.

>
> >

>
> >

>
> > Here's an example for Linux shell, otherwise remove /bin/env...

>
> > {{{#!/bin/env python

>
> > a=[1,2,3,4,5,6,7,8,9,10]

>
> > print a[-4:3] # I am interested in getting [7,8,9,10,1,2] but I get [].

>
> > }}}

>
>
>
>
>
> For a sequence of length 10, "a[-4:3]" is equivalent to "a[6:3]",
>
> which is an empty slice since index 6 is after index 3.
>
>
>
> If you want it to wrap around, then take two slices and concatenate
>
> them with "a[-4:] + a[:3]".


Hi Ian,
Well, no it really isn't equivalent; although Python implements it as equivalent.

Consider a programmer who writes:
xrange(-4,3)

They clearly *want* [-4,-3,-2,-1,0,1,2]

That is the "idea" of a range; So, for what reason would anyone want -4 to +3 to be 6:3??? Can you show me some code where this is desirable??

I do agree that the data held in -4 is equivalent to the data in 6, but the index is not the same.

So: Why does python choose to convert them to positive indexes, and have slice operate differently than xrange -- for the slice() object can't possibly know the size of the array when it is passed in to __getitem__; They are totally separate classes.

I realize I can concat. two slice ranges, BUT, the ranges do not always span from negative to positive.

eg: a line in my program reads:
a[x-5]

if x is 7, then this is a positive index to a positive index.
So, there is no logic to using two slices concatd !

I use this arbitrary range code *often* so I need a general purpose solution.
I looked up slice() but the help is of no use, I don't even know how I might overload it to embed some logic to concatenate ranges of data; nor even if it is possible.
 
Reply With Quote
 
Ian Kelly
Guest
Posts: n/a
 
      10-29-2012
On Sun, Oct 28, 2012 at 10:00 PM, <(E-Mail Removed)> wrote:
> Hi Ian,
> Well, no it really isn't equivalent.
> Consider a programmer who writes:
> xrange(-4,3) *wants* [-4,-3,-2,-1,0,1,2]
>
> That is the "idea" of a range; for what reason would anyone *EVER* want -4 to +3 to be 6:3???


That is what ranges do, but your question was about slices, not ranges.

> So: Why does python choose to convert them to positive indexes, and have slice operate differently than xrange -- for the slice() object can't possibly know the size of the array when it is passed in to __getitem__; They are totally separate classes.


Ranges can contain negative integers. However, sequences do not have
negative indices. Therefore, negative indices in slices are used to
count from the end instead of from the start. As stated in the
language docs, "If either bound is negative, the sequence’s length is
added to it." Therefore, "a[-4:3]" does not wrap around the end of
the sequence because "a[6:3]" does not wrap around the end of the
sequence.

> I realize I can concat. two slice ranges, BUT, the ranges do not always span from negative to positive.


def wrapping_slice(seq, start, stop):
start, stop, _ = slice(start, stop).indices(len(seq))
if start <= stop:
return seq[start:stop]
else:
return seq[start:] + seq[:stop]

You'll have to decide for yourself whether you want it to return an
empty list or the entire list if start == stop.
 
Reply With Quote
 
alex23
Guest
Posts: n/a
 
      10-29-2012
On Oct 29, 2:09*pm, Andrew <(E-Mail Removed)> wrote:
> I use this arbitrary range code *often* so I need a general purpose solution.
> I looked up slice() but the help is of no use, I don't even know how I might
> overload it to embed some logic to concatenate ranges of data; nor even if
> it is possible.


Slices are passed in if provided to __getitem__/__setitem__/
__delitem__, so you'd need to override it at the list level:

class RangedSlicer(list):
def __getitem__(self, item):
# map item.start, .stop and .step to your own semantics

Then wrap your lists with your RangedSlicer class as needed.
 
Reply With Quote
 
Andrew Robinson
Guest
Posts: n/a
 
      10-29-2012
On 10/29/2012 04:32 AM, Chris Angelico wrote:
> I wonder if what the OP is looking for is not slicing, but something
> more akin to map. Start with a large object and an iterator that
> produces keys, and create an iterator/list of their corresponding
> values. Something like: a=[1,2,3,4,5,6,7,8,9,10] b=[a[i] for i in
> xrange(-4,3)] It's not strictly a slice operation, but it's a similar
> sort of thing, and it can do the wraparound quite happily. ChrisA


A list comprehension ?
That does do what I am interested in, *very* much so. Quite a gem, Chris!

:-\
I am curious as to how quickly it constructs the result compared to a
slice operation.

Eg:
a[1:5]
vs.
[ a[i] for i in xrange[1:5] ]

But, unless it were grossly slower -- so that if/then logic and slices
were generally faster -- I will use it.
Thanks.

--Andrew.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Negative array indicies and slice() Ian Kelly Python 0 10-31-2012 07:43 AM
Re: Negative array indicies and slice() Dennis Lee Bieber Python 0 10-31-2012 03:36 AM
Re: Negative array indicies and slice() Ethan Furman Python 0 10-30-2012 09:21 PM
Re: Negative array indicies and slice() Mark Lawrence Python 0 10-29-2012 10:10 AM
Re: Negative array indicies and slice() Andrew Robinson Python 0 10-29-2012 02:31 AM



Advertisments