Drop That Nested Dictionary; Use elementtree

| | Comments (6) |
Tree-like dictionaries are gross and hard to work with. Use elementtree for nested data.

In Python, most people's instinct is to model tree-like structures with nested dictionaries. An organization chart from a nuclear power plant is a simple example:


powerplant_org_chart.png



The old me would have rushed to model this like so:
org = {'name':'Monty',
       'title':'CEO',
       'boss_of':[
                  {'name':'Waylon',
                     'title':'Flunkie',
                     'boss_of':[
                                  {'name':'Carl',
                                   'title':'Engineer',
                                   'boss_of': None},
                                  {'name':'Lenny',
                                   'title':'Engineer',
                                   'boss_of': None},
                                  {'name':'Homer',
                                   'title':'Safety Iinspector',
                                   'boss_of': None}
                                 ]
                    }]
    }

This is annoying to type and even harder to read. Keeping track of quotes, brackets and commas is frustrating. Imagine the pain when of a larger or more complex tree.

Fear not. elementtree makes things super-easy when dealing with nested data.

"But wait", you say. "You're not doing XML!"

Say it with me: elementtree is not XML. Yes, it's good at serializing to and de-serializing from XML, but it's very useful even if you never read or generate a lick of markup.

Here's the same org chart using Element. Much shorter, less error-prone, and easier on the eyeballs:

from elementtree.ElementTree import Element
from elementtree.ElementTree import SubElement


burns = Element('emp', name="Monty", title="CEO")
smithers = SubElement(burns, 'emp', name="Waylan", title="Flunkie")
karl = SubElement(smithers, 'emp', name="Carl", title="Engineer")
lenny = SubElement(smithers, 'emp', name="Lenny", title="Engineer")
homer = SubElement(smithers, 'emp', name="Homer", title="Inspector")

I didn't create a whole class to help me model the nested data; that would have been overkill. I just used Elements  to string together related data. Now it's easy to navigate the tree in idiot-proof fashion with methods like getchildren and getiterator.

Nested data pops up quite often, and it's nice to have a good tool for dealing with it gracefully.

6 Comments

Matt Wilson Author Profile Page said:

I had no idea that element tree could be used this way. Seems obvious in retrospect. Thanks for writing this up!

I'm determined to shoehorn this into some code as soon as possible. I can imagine that the selectors and traversal methods in elementtree will save a lot of time and lines of code for me.

I thought you just wrote blogs about HR issues!

Aaron Author Profile Page said:

Coolio. Let me know how it goes. I'm finding myself using it more and more in non-XML scenarios. It's a great addition to the toolkit.

As for the nature of my posts, I'd like to think CS can be a mix of all aspects of software engineering, from dealing with people to wrangling electrons. So far, the people posts are easier for me to write (no code examples needed!), but I'm hoping to get more of a balance going.

dave noyes said:

I have to agree. That's pretty cool. This is why I work places with smart people. They can do all the hard work for me.

tom said:

Attributes can only be text - this is nice but works only for very simple applications.

Aaron Author Profile Page said:

Thanks for the comment, Tom! I put up a whole post dealing with just that issue: http://www.codesoftly.aaronoliver.com/2008/08/assign-objects-to-elementtree-attributes.html

Leave a comment


About this Entry

This page contains a single entry by Aaron Oliver published on August 4, 2008 10:51 PM.

You Don't Work as Hard as You Think You Do was the previous entry in this blog.

Ginormous List of CSS Resources is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Web Hosting By ICDSoft.com