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