3

I'm doing some calculation in python and I have to sum items from a list, if they are on the list. This is the code:

Ei=-J*S[i][j]*(S[i+1][j]+S[i-1][j]+S[i][j+1]+S[i][j-1])

what I want is to make zero the value of the element that gives the error list index out of range. Is there a way to do this without verifying if every element of the sum exists?

thanks in advance

Edit

I don't want the sum to be 0, only the element that gives the error

Rasmnev
  • 109
  • 2
  • 11

4 Answers4

6

You could write a function using try/except

def get_value(S, i, j):
    try:
        return S[i][j]
    except IndexError:
        return 0

Then to use it

 Ei = -J * get_value(S, i, j) * (get_value(S, i+1, j) + get_value(S, i-1, j) +get_value(S, i, j+1) + get_value(S, i, j-1))
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • I don't want the sum to be 0, just the element that caused the error – Rasmnev Jun 03 '15 at 16:33
  • @Rasmnev Then you need to be more clear when asking your question, by showing examples for inputs and desired outputs. If 3 different people misunderstood the intention of your question, then you did not ask it clearly. I have edited my post. – Cory Kramer Jun 03 '15 at 16:34
  • I'm sorry. I'll try to be more clear next time and I'll update the question – Rasmnev Jun 03 '15 at 16:36
4

subclass list and override __getitem__:

class zlist(list):
    def __getitem__(self,n):
        if len(self) <= n:
            return 0
        return super(zlist, self).__getitem__(n)

If need to handle multi-dimentional lists, you can do something like this:

class zlist(list):
    def __init__(self, dim=1, *args):
        list.__init__(self, *args)
        self.dim = dim

    def __getitem__(self,n):
        if len(self) <= n:
            if self.dim > 1:
                return zlist(self.dim-1)
            else:
                return 0

        return super(zlist, self).__getitem__(n)

Also, take a look at Is there a simple way to override the list object's method __getitem__?, which is similar, but extends the list with missing values instead.

Finally, for completeness, if you just want to have a zero-filled multi-dimentional array, use numpy: http://docs.scipy.org/doc/numpy/reference/generated/numpy.zeros.html

Community
  • 1
  • 1
ykaganovich
  • 14,736
  • 8
  • 59
  • 96
0

When I read this, I immediately though of subclassing list and adding a get() method that functions similar to dict.get().

class MyList(list):
    def get(self, idx, default=None):
        try:
            return self.__getitem__(idx)

        except IndexError:
            return default

my_list = MyList(range(6))
assert my_list == [0, 1, 2, 3, 4, 5]
assert my_list.get(0, 0) == 0
assert my_list.get(5, 0) == 5
assert my_list.get(10, 0) == 0
Deacon
  • 3,615
  • 2
  • 31
  • 52
-1

Here is the simple and much better approach then accepted one.

def get_value(a, i, j):
    if i <0 or j <0:
        return 0
    try:
        return a[i][j]
    except IndexError:
        return 0

because when i and j will be negative still that is valid in python. For example, you are at (3,0) and need (3-1, 0-1) value that is (2, -1), actually it is out of bound but it will give last element of 2nd array.

Yash
  • 1,787
  • 1
  • 22
  • 23