array of class attributes
Tracy Ruggles
tracer at axiomfire.com
Mon Apr 5 23:55:00 EDT 2004
beliavsky at aol.com wrote in message news:<3064b51d.0404050810.62617907 at posting.google.com>...
> Suppose I define a trivial class composed of x and y coordinates and
> create a Numeric array of instances of that class.
>
> class xy:
> def __init__(self,x=0.0,y=0.0):
> self.x = x
> self.y = y
> def __repr__(self):
> return ("%6.2f" % self.x) + (",%6.2f" % self.y)
>
> from xy import xy
> from Numeric import zeros,array,PyObject
> n = 3
> aa = array([xy() for i in xrange(n)], PyObject)
> aa[1] = xy(5.0,25.0)
> print aa
> # not legal -- print aa.x
>
> The output of this program is
> [ 0.00, 0.00 5.00, 25.00 0.00, 0.00 ] .
>
> I would like to be able to get an array [0.00 5.00 0.00] corresponding
> to the x component of array aa using the syntax aa.x, but this is not
> correct Python. Array slices of components would also be nice. I
> could write a function to return such an array, but I doubt that this
> would be efficient in CPU time or memory. I wonder if this capability
> could be added to Numarray, the successor of Numeric. Otherwise, it
> may be better to write numerical codes using parallel arrays (one for
> x, one for y) instead of classes, and the benefits of classes are
> lost.
Here's a way to kinda get what you want:
from numarray import zeros, Float
class space(object):
def __init__(self, n=3):
self.points = zeros((n,2), Float)
def __getitem__(self, i):
return xy(self.points[i])
def __setitem__(self, i, (x,y)):
self.points[i,0] = x
self.points[i,1] = y
def __repr__(self):
return repr(self.points)
# or, '\n'.join([repr(p) for p in self.points])
x = property(lambda self: self.points[:,0])
y = property(lambda self: self.points[:,1])
class xy(object):
def __init__(self, loc):
self.loc = loc
def __repr__(self):
return '%2.6f, %2.6f' % (self.x, self.y)
def _get_x(self): return self.loc[0]
def _set_x(self, value): self.loc[0] = value
x = property(_get_x, _set_x)
def _get_y(self): return self.loc[1]
def _set_y(self): self.loc[1] = value
y = property(_get_y, _set_y)
n = 3
aa = space(n)
aa[1] = (5.0, 25.0)
print aa
print aa.x
---
Using the array slicing, "array[:,i]" seems to be pretty efficient to
me. You can also use that syntax for setting values. The xy class
now is just a convenience wrapper/pointer to its position in space...
One improvement on this might be to allow slicing of space so you can
do something like:
>>> a,b,c = aa[100:103] # to get 3 discreet points
>>> aa[50:55] = [(1.,2.), (2.,3.), (3.,4.), (4.,5.), (5.,6.)] # to
set multiple points
--T
More information about the Python-list
mailing list