Take the 2-minute tour ×

I need to have a dictionary which might have same names for some keys and return a list of values when referencing the key in that case. For example

print mydict['key']
share|improve this question
No, but you can use mydict = {'key':[1,2,3,4]} –  Artsiom Rudzenka Jul 25 '11 at 8:47
keys are added at runtime –  b9107007 Jul 25 '11 at 8:49

5 Answers 5

For consistency, you should have the dictionary map keys to lists (or sets) of values, of which some can be empty. There is a nice idiom for this:

from collections import defaultdict
d = defaultdict(set)


(A defaultdict is like a normal dictionary, but if a key is missing it will call the argument you passed in when you instantiated it and use the result as the default value. So this will automatically create an empty set of values if you ask for a key which isn't already present.)

If you need the object to look more like a dictionary (i.e. to set a value by d["key"] = ...) you can do the following. But this is probably a bad idea, because it goes against the normal Python syntax, and is likely to come back and bite you later. Especially if someone else has to maintain your code.

class Multidict(defaultdict):
    def __init__(self):
        super(Multidict, self).__init__(set)

    def __setitem__(self, key, value):

I haven't tested this.

share|improve this answer

You can also try paste.util.multidict.MultiDict

$ easy_install Paste


from paste.util.multidict import MultiDict
d = MultiDict()
d.add('a', 1)
d.add('a', 2)
d.add('b', 3)
>>> {'a': [1, 2], 'b': 3}
>>> [1, 2]
>>> [3]

Web frameworks like Pylons are using this library to handle HTTP query string/post data, which can have same-name keys.

share|improve this answer

You can use:

myDict = {'key': []}

Then during runtime:

if newKey in myDict:
    myDict[newKey] = [value]

Edited as per @Ben's comment:

myDict = {}
myDict.setdefault(newKey, []).append(value)
share|improve this answer
Its' more idiomatic to day myDict.setdefault(newKey, []).append(value) –  Ben Ford Jul 25 '11 at 9:38
Sure, thank you @Ben –  Artsiom Rudzenka Jul 25 '11 at 9:45
def toMultiDict(items):
    def insertMulti(d, kv):
        k, v = kv
        d.setdefault(k, []).append(v)
        return d
    return reduce(insertMulti, [{}] + items)

should create a dict from key to a list of values:

In [28]: toMultiDict(zip([1,2,1], [4,5,6]))
Out[28]: {1: [4, 6], 2: [5]}

I couldn't put insertMulti into a lambda, because the lambda needs to return the dict again.

share|improve this answer

This is an ideal place to use a defaultdict object from the collections library

from collections import defaultdict

mydict = defaultdict(set)
mydict['key'] += set([1,2,3,4])
mydict['key'] += set([4,5,6])


returns [1,2,3,4,5,6]

In the case where a key is referenced that has not been implicitly assigned, an empty set is returned.


returns []

Using setdefault on a dict from the standard library would require a significant change in your syntax when assigning values and can get rather messy. I've never used Multidict, but it also looks like a significant change in the way assignments are made. Using this method, you simply assume that there may already be a value associated with this key in the dictionary and slightly modify your assignment operator by using the '+=' operator when assigning key values.

FYI - I am a big fan of using the NoneType as the default which results in any access of an invalid key returning None. This behaves properly in most cases including iterating and json dumps, but for your specific need the default should be of type set unless you want to enable having duplicate values stored in the key. Then use a list. In fact, anytime you have a homogenous dictionary the default should be of that type.

mydict = defaultdict(lambda: None)
share|improve this answer

Your Answer


