Home

Python tip (dictionaries)


Python type objects like dict (Associative array or hash) has lots of cool little methods that I didn’t know about.

Some of them I use a lot like:

k in a which really maps to a.has_key(k)

The dict type also has a pop() method which I don’t really use a lot with dictionaries, but I do use it a lot with list types. I also use the insert() and append() methods of lists quite often.

When working with dict or mapping-types in Python you get the value at a specified index like you might expect:

d = {} # {} is short-hand for dict()
d['name'] = 'clint'

However, if you want to do something like this:

d = {}
stuff = ['one', 'one', 'two', 'three', 'four', 'four']
for item in stuff:
  d[item] = d[item] + 1

You will most certainly be greeted with a swift KeyError exception from the Python interpreter. The issue here is when you try to retreive the value of d[item] so that you can add 1 to it and then save it back to the dictionary. Initially that key doesn’t exist so you get the KeyError. If you use PHP a lot you might be caugh off-guard. In PHP if the key doesn’t exist PHP will realise that you want to use that index and define it and assign it a value of 0.

So to get around this I’ve been using some ugly try/except blocks to perform a different action on the first use of a key like such:

d = {}
stuff = ['one', 'one', 'two', 'three', 'four', 'four']
for item in stuff:
    try:
        d[item] = d[item] + 1
    except KeyError: # perform this block
                      # if a KeyError exception is thrown
        d[item] = 1

I really hate catching errors because basically I don’t like generating errors in the first place! Plus catching exceptions can sometimes cover up other issues if you don’t ratchet down which exceptions you want to catch. Often times its much too easy to not specify an exception to catch and just catch them all. That little mistake has led to a bit more than a little grief :)

To the point of this post: Today someone online showed me a much cleaner and nicer way of performing the above with a little dict method named get(). The definition of this method is:

a.get(k[, x]) ----> a[k] if k in a, else x

with a little note that says:

Never raises an exception if k is not in the map, instead it returns x. x is optional; when x is not provided and k is not in the map, None is returned.

So the above can be simplified to:

d = {}
stuff = ['one', 'one', 'two', 'three', 'four', 'four']
for item in stuff:
    d[item] = d.get('item',0) + 1

If the key named the value of item doesn’t exist, the get() method will just return 0 and add 1 to that. Nice, clean, and simple!