Python lists/arrays: disable negative indexing wrap-around in slices
00:36 16 Nov 2012

The negative number wraparound (i.e. A[-2] indexing the second-to-last element) is useful in many cases, but when it happens inside a slice it can more of an annoyance than a helpful feature. I've often wished for a way to disable that behavior.

Here is a 2D example

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

example

def foo(i, j, r=2):
    """sum of neighbors 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 want any negative number used in the slice to be treated the same as None is, rather than wrapping to the other end of the array.

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

def clamp(n):
    return None if n < 0 else n

def ugly_foo(i, j, r=2):
    return A[clamp(i-r):i+r+1, clamp(j-r):j+r+1].sum()

I've tried zero-padding the array or list, but that is still inelegant (requires offsetting the lookup locations indices accordingly) and inefficient (requires copying the array).

Is there a standard trick or elegant solution for slicing without wrapping? Notice 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.

python arrays list numpy slice