Roose wrote: > I think someone mentioned that it might be a problem to add another > piece of state to all dicts though. I don't know enough about the > internals to say anything about this. > > setdefault gets around this by having you pass in the value every > time, so it doesn't have to store it. It's very similar, but somehow > many times more awkward. >
Another option with no storage overhead which goes part way to reducing the awkwardness would be to provide a decorator class accessible through dict. The decorator class would take a value or function to be used as the default, but apart from __getitem__ would simply forward all other methods through to the underlying dictionary. That gives you the ability to have not one default value for a dictionary, but many different ones: you just decorate the dictionary anywhere you need a default and use the underlying dictionary everywhere else. Some code which demonstrates the principle rather than the implementation. dictDefaultValue could be imagined as dict.defaultValue, dictDefaultValue(d, ...) could be d.defaultValue(...) although the actual name used needs work: >>> class dictDefaultValue(object): def __init__(self, d, value=_marker, function=_marker): self.__d = d if value is _marker: if function is _marker: raise TypeError, "expected either value or function argument" self.__dv = function else: def defaultValue(): return value self.__dv = defaultValue def __getattr__(self, name): return getattr(self.__d, name) def __getitem__(self, name): try: return self.__d[name] except KeyError: value = self.__dv() self.__d[name] = value return value def __setitem__(self, name, value): self.__d[name] = value >>> d = {} >>> accumulator = dictDefaultValue(d, 0) >>> accumulator['a'] += 1 >>> aggregator = dictDefaultValue(d, function=list) >>> aggregator['b'].append('hello') >>> d {'a': 1, 'b': ['hello']} >>> -- http://mail.python.org/mailman/listinfo/python-list