Friday, March 22, 2013

Python: Dict Comprehension Example

Just like list comprehensions, dictionary comprehensions help the Python programmer quickly construct an alternative structure from something more permanent. The application we're working with probably has a schema, and from that, we can only do so much as we implement new functionality over time. So rather than alter the data model that supports the application, why not create something transient? This is where the comprehension idea is powerful, at very efficiently constructing new data sources. You can use this approach to creating new lists and dictionaries that stick around for the duration of the program, but a more useful use case is in creating a temporary search space.

List comprehensions are good and this sort of temporary storehouse of objects — you see them everywhere nowadays. And so why not dict comprehensions too? For example, to quickly look something up by ID.

import uuid

class Person(object):

    def __init__(self, first_name, last_name):
        self.uuid = str(uuid.uuid4())
        self.first_name = first_name
        self.last_name = last_name

    def __repr__(self):
        return '%s %s <%s>' % (
            self.first_name,
            self.last_name,
            self.uuid
        )

people = (
    Person('Julia', 'Weinstein'),
    Person('Sydney', 'Iverson'),
    Person('Gracie', 'Proctor'),
    Person('Jonah', 'Brower'),
    Person('Austin', 'Mays'),
    Person('Collin', 'Vick')
)

if __name__ == '__main__':

    id_for_search = people[0].uuid

    print {p.uuid:p for p in people}[id_for_search]

Here we have a tuple of people, and we want to quickly lookup someone by UUID. Given our Person class, and the tuple storing the instances, there is no way for us to do this without creating a new structure, or by looping through the people and explicitly checking if the uuid property matches the one we're looking for. Instead, we have a dictionary we've created on-the-fly, it's existence is transient because we only need it for one task. We can afford to build dictionaries this way because comprehensions are efficient.

The syntax is simple enough too.  We have the curly braces, the familiar dictionary format, and we have key:value.  The for loop inside the braces is no different from that of a list comprehension.