Sunday, November 17, 2013

Python Dictionary Comprehension

Dictionary comprehensions were backported from Python 3.x to 2.7. I always have believed that they are very pythonic and functional way of programming. Whenever comprehension is used, mutation of mutable elements (set, dict, list etc) becomes unnecessary and that definitely improves the performance as well. Lets start with a simple dictionary comprehension

>>> myMatrix = [[1, 100], [2, 200], [3, 300]]
>>> {key:value for key, value in myMatrix}
{1: 100, 2: 200, 3: 300}

Here we use unpacking from myMatrix list and we have used {} with key:value notation. This way, we can easily convert a list of lists to a dictionary with dictionary comprehension. Lets look at a complicated example

>>> myMatrix = [[100, 100], [20, 200], [30, 300]]
>>> {(key + 100 if key < 100 else key):(value/10 if value >= 200 else value/5) for key, value in myMatrix}
{120: 20, 130: 30, 100: 20}

Here we use conditional expressions to dynamically decide what the key and the value are going to be.

Performance

>>> def changeDict():
...     newDict = {}
...     for key, value in myMatrix:
...         newDict[(key + 100 if key < 100 else key)] = value/10 if value >= 200 else value/5
...     return newDict
...     
>>> from timeit import timeit
>>> timeit("{(key + 100 if key < 100 else key):(value/10 if value >= 200 else value/5) for key, value in myMatrix}", setup="from __main__ import myMatrix")
0.7076609134674072
>>> timeit("changeDict()", setup="from __main__ import myMatrix, changeDict")
0.7484149932861328

The use of comprehension is slightly faster than the function which adds keys and values to an existing dictionary. This difference will be significant when the myMatrix has huge amount of data.