magical expanding hash

Giovanni Bajo noway at sorry.com
Tue Jan 17 08:04:32 EST 2006


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





More information about the Python-list mailing list