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