FWIW, here is my take on the defaultdict approach:
def defaultdict(defaultfactory, dictclass=dict): class defdict(dictclass): def __getitem__(self, key): try: return super(defdict, self).__getitem__(key) except KeyError: return self.setdefault(key, defaultfactory()) return defdict
d = defaultdict(int)() d["x"] += 1 d["x"] += 1 d["y"] += 1 print d
d = defaultdict(list)() d["x"].append(1) d["x"].append(2) d["y"].append(1) print d
Michele Simionato
Very pretty! =)
It does mean, however, that if the defaultfactory function takes any arguments, you have to wrap the function to make this work. I'd probably prefer something like:
py> def defaultdict(*args, **kwargs):
... defaultfactory, args = args[0], args[1:]
... class defdict(dict):
... def __getitem__(self, key):
... try:
... return super(defdict, self).__getitem__(key)
... except KeyError:
... return self.setdefault(key, defaultfactory(
... *args, **kwargs))
... return defdict
...
py> d = defaultdict(int)()
py> d['x'] += 1
py> d['x'] += 1
py> d['y'] += 1
py> d
{'y': 1, 'x': 2}
py> d = defaultdict(list, [0])()
py> d['x'].append(1)
py> d['x'].append(2)
py> d['y'].append(1)
py> d
{'y': [0, 1], 'x': [0, 1, 2]}That said, I still think a dictools module is a better solution to this problem.
STeVe -- http://mail.python.org/mailman/listinfo/python-list
