Python lists/arrays: disable negative indexing wrap-around

Posted by wim on Stack Overflow See other posts from Stack Overflow or by wim
Published on 2012-11-16T04:47:04Z Indexed on 2012/11/16 5:00 UTC
Read the original article Hit count: 160

Filed under:
|
|
|
|

While I find the negative number wraparound (i.e. A[-2] indexing the second-to-last element) extremely useful in many cases, there are often use cases I come across where it is more of an annoyance than helpful, and I find myself wishing for an alternate syntax to use when I would rather disable that particular behaviour.

Here is a canned 2D example below, but I have had the same peeve a few times with other data structures and in other numbers of dimensions.

import numpy as np
A = np.random.randint(0, 2, (5, 10))

enter image description here

def foo(i, j, r=2):
  '''sum of neighbours within r steps of A[i,j]'''
  return A[i-r:i+r+1, j-r:j+r+1].sum()

In the slice above I would rather that any negative number to the slice would be treated the same as None is, rather than wrapping to the other end of the array.

Because of the wrapping, the otherwise nice implementation above gives incorrect results at boundary conditions and requires some sort of patch like:

def ugly_foo(i, j, r=2):
  def thing(n):
    return None if n < 0 else n
  return A[thing(i-r):i+r+1, thing(j-r):j+r+1].sum()

I have also tried zero-padding the array or list, but it is still inelegant (requires adjusting the lookup locations indices accordingly) and inefficient (requires copying the array).

Am I missing some standard trick or elegant solution for slicing like this? I noticed that python and numpy already handle the case where you specify too large a number nicely - that is, if the index is greater than the shape of the array it behaves the same as if it were None.

© Stack Overflow or respective owner

Related posts about python

Related posts about arrays