Michele Simionato wrote:
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

Reply via email to