Python OrderedDict __setitem__ overloading
<p>I'm building a class that inherits OrderedDict, in which every key returns a list. I'm looking to overload <strong>setitem</strong> such that if the key doesn't exist, new assignments immediately put the value into a list, otherwise the new value is appended to the list. The following seems to be working:</p>

<pre><code>from collections import OrderedDict

class ListDict(OrderedDict):
    def __init__(self):
        super(ListDict, self).__init__()

    def __setitem__(self, key, value):
        if key in self.keys():
            self[key].append(value)
        else:
            super(ListDict, self).__setitem__(key, [value])

thedict = ListDict()

thedict['a'] = 'first item'
thedict['b'] = 'another first item'
thedict['a'] = 'a second item?'

print thedict
</code></pre>

<p>which prints:</p>

<pre><code>$ python inheritex.py
ListDict([('a', ['first item', 'a second item?']), ('b', ['another first item'])])
</code></pre>

<p>Instead of appending with an assignment operator '=', I would rather have new items be appended with '+=', or even something like:</p>

<pre><code>ListDict['key'] = ListDict['key'] + 'value'
</code></pre>

<p>How would one go about overloading this? Besides being possible to monkey patch an add function, is it even a Pythonic/readable means to alter class behavior, or is this acceptable because the inherited function (OrderedDict) is untouched?</p>

<p>I've extended <a href="http://stackoverflow.com/users/100297/martijn-pieters">Martijn's</a> <code>ListDict</code> so you can provide <code>default_factory</code> and have a similar to <a href="https://docs.python.org/3/library/collections.html#collections.defaultdict" rel="nofollow"><code>collections.defaultdict</code></a>'s functionality + key ordering:</p>

<pre><code>class OrderedDefaultDict(OrderedDict):
    def __init__(self, default_factory=None):
        self.default_factory = default_factory

    def __missing__(self, key):
        if self.default_factory is None:
            raise KeyError
        self[key] = self.default_factory()
        return self[key]

list_dict = OrderedDefaultDict(list)
list_dict['first'].append(1)
list_dict['second'].append(2)
list_dict['third'].append(3)
assert list(list_dict.keys()) == ['first', 'second', 'third']
assert list(list_dict.values()) == [[1], [2], [3]]

list_dict.move_to_end('first')
assert list(list_dict.keys()) == ['second', 'third', 'first']
</code></pre>

python dictionary overloading ordereddictionary