James Stroud wrote: >> I need a magical expanding hash with the following properties: >> >> * it creates all intermediate keys >> >> meh['foo']['bar] = 1 >> >> -- works even if meh['foo'] didn't exist before >> >> * allows pushing new elements to leaves which are arrays >> >> meh['foo']['list] << elem1 >> meh['foo']['list] << elem2 >> >> * allows incrementing numeric leaves >> >> meh['foo']['count'] += 7 >> >> * serializable >> >> I have such a class in ruby. Can python do that? >> > > > Is this too magical? > > > class meh(dict): > def __getitem__(self, item): > if self.has_key(item): > return dict.__getitem__(self, item) > else: > anitem = meh() > dict.__setitem__(self, item, anitem) > return anitem
Actually what the OP wants is already a method of dict, it's called setdefault(). It's not overloaded by "[]" because it's believed to be better to be able to say "I want auto-generation" explicitally rather than implicitly: it gives the user more power to control, and to enforce stricter rules. >>> class meh(dict): ... def __getitem__(self, item): ... return dict.setdefault(self, item, meh()) ... >>> a = meh() >>> a["foo"]["bar"] = 2 >>> a["foo"]["dup"] = 3 >>> print a["foo"]["bar"] 2 >>> print a {'foo': {'dup': 3, 'bar': 2}} So I advise using this class, and suggest the OP to try using setdefault() explicitally to better understand Python's philosophy. BTW: remember that setdefault() is written "setdefault()" but it's read "getorset()". -- Giovanni Bajo -- http://mail.python.org/mailman/listinfo/python-list