Thanks to everyone who responded to my "Prevent Coder's Remorse" posting; the result of combining the ideas that you contributed is below.
It's a little long, but I'm delighted with it so far, and maybe someone else can use it. It's nice for representing a sparse table, where all the records share columns, but a lot of the values in any given column are the same. Geographic points (my original question) are just a special case. One example is a table where the Null value isn't predefined but is represented by a 'magic value' that means null in that table. I realize now that I might have been better off just to use a database; they know all about nulls, tables. types, defaults, etc. Still, I learned a LOT. So, no remorse! Thanks again, Ron #magicvaluetable.py ################################### # -*- coding: utf-8 -*- #may use a guid to keep things straight import guid # Make it work with Python 2.3 try: set except NameError: from sets import Set as set class MVTRecord(dict): """A record belonging to a magic value table (MVTable). Requires a parent MVTable and an id assigned by it. Other attributes (column values) may be assigned. Attributes not specifically assigned at the record level are deferred to the parent MVTable's attDict.""" def __init__(self,mvtParent,id,**args): dict.__init__(self) self.mvtParent = mvtParent self.id = id for arg in args: self[arg]=args[arg] def __getitem__(self, key): if key in self.keys(): return dict.__getitem__(self, key) else: return self.mvtParent.attDict[key] raise KeyError,'Key "%s" was not found in MVTRecord or MVTable'%key def __setitem__(self, key, value): (nullValue,valueType)=self.__testType(value) if key not in self.mvtParent.attDict.keys(): self.mvtParent.addAttribute(key,nullValue) (whoCares,columnType)=self.__testType(self.mvtParent.attDict[key]) # make sure what's set is proper type or can degrade to proper type if valueType == columnType: dict.__setitem__(self, key, value) else: if columnType == 'float'and valueType=='int': dict.__setitem__(self, key, float(value)) elif columnType == 'string': dict.__setitem__(self, key, str(value)) else: msg = 'The %s attribute requires %s data'%(key, columnType) raise ValueError,msg def __delitem__(self, key): if key in self.keys(): dict.__delitem__(self, key) elif key in self.mvtParent.attDict.keys(): pass else: raise KeyError,'Key "%s" was not found in MVTRecord or MVTable'%key def __testType(self, value): try: if str(value)==str(int(value)): test = (self.mvtParent.nullInt,'int') else: test = (self.mvtParent.nullFloat,'float') except ValueError: test=(self.mvtParent.nullString,'string') return test class MVTable(object): """Defines a group of records (MVTRecord) with common columns. Attributes (record values in a given column) which are not specified at the record level are deferred to the MVTable attDict. Note: the nullInt, nullFloat, and nullString are designed to hold 'magic values' for use with data structures(CSV, DBF) having no defined 'null'.""" def __init__(self, nullInt=0, nullFloat=0.0, nullString='null'): self.nullInt=nullInt self.nullFloat = nullFloat self.nullString = nullString self.attDict = {} self.membersDict = {} def addMember(self,id=None,**args): if not id: id = guid.generate() self.membersDict[id]=MVTRecord(self,id=id,**args) return self.membersDict[id] def delMember(self,member): del self.membersDict[member.id] def addAttribute(self, name, nullValue=None): if nullValue == None:nullValue=self.nullString self.attDict[name]=nullValue def delAttribute(self, name): for member in self.membersDict: if member.has_key(name):del member[name] del self.attDict[name] def compactAttributesDictionary(self): """removes unreferenced attributes""" newkeys = set() for member in self.membersDict: for key in self.membersDict[member].keys(): newkeys.add(key) for key in self.attDict.keys(): if key not in newkeys: del self.attDict[key] if __name__ == "__main__": mvt = MVTable() me=mvt.addMember() he=mvt.addMember(third=3, fourth=4) mvt.addAttribute('first', 5) #print basic functionality outputs for column in mvt.attDict: print 'Column:%s, me:%s, he:%s'%(column,me[column],he[column]) ########################### _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor