Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am using Python 3.2.3 with NumPy 1.6.1. I would be very grateful if someone could explain me what does NumPy do when I try to access (in two different ways) an element of a NumPy array.

Code:

import numpy as np

class MyClass:

    def __init__(self,q):
        self.coord = q
        self.firstel = q[0]
        self.secondel = q[1:2]

q = np.array([10,20])   # numpy array
my_object = MyClass(q)  # object of MyClass

print('original','q:',q,' / coord:',my_object.coord,' / 2elements:',my_object.firstel,my_object.secondel])

q[0],q[1] = 30,40 # modification of the  elements of q

print('modified','q:',q,' / coord:',my_object.coord,' / elements:', my_object.firstel, my_object.secondel])

q is a numpy array that I pass as an argument to MyClass. I store it in a variable called coord inside the class. Then I access the first and the second element of q in two different ways inside the class.

When I run the code above, I get this:

original q: [10 20]  / coord: [10 20]  / elements: [10, array([20])]
modified q: [30 40]  / coord: [30 40]  / elements: [10, array([40])]

The variable firstel is not updated when q is changed but the variable secondel is.

What happened with q[0] and q[1:2] ?

Thanks

share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

The firstel variable is a (immutable) value and thus never updated:

self.firstel = q[0]  # and stays this value once and for all

whilst the secontel variable is a view on the original array and so will be updated:

self.secondel = q[1:2]

.

One way to solve this would be to make firstel a method:

def firstel(self):
    return self.q[0]

This probably makes it clearer what the intent of firstel and secondel is in your class.

share|improve this answer
    
Thanks ! It is clear. I was expecting something like this. Just a comment: there was no actual "problem" in my question but rather 2 different behaviours that I wanted to understand. –  RolPasto Jun 4 '13 at 12:50
add comment

Andy's explanation is spot on. As to how to overcome that limitation, I don't like having to type empty parentheses all over the place, so for this kind of class attributes I prefer to go with properties, probably influenced by numpy's shape, dtype and the like:

class MyClass(object):

    def __init__(self, q):
        self.coord = np.asarray(q)

    @property
    def firstel(self):
        """The first element of self.coord"""
        return self.coord[0]

    @property
    def secondel(self):
        """The second element of self.coord"""
        return self.coord[1]

And now:

>>> q = np.array([10, 20])
>>> my_object = MyClass(q)
>>> my_object.firstel
10
>>> my_object.secondel
20
>>> q[:] = [30, 40]
>>> my_object.firstel
30
>>> my_object.secondel
40
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.