Welcome, guest | Sign In | My Account | Store | Cart

Sometimes, especialy if you are working with database object mappers, you encounter deeply nested dictionaries. You want to access a particular leaf item and you have in your hand the long, decorated, name. reduce can be your friend!

Python, 18 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# In your hand you have a dict instance representing the database 'object'
dbo={'m':{'d':{'v':{'version':1}}}}

# You know this thing corresponds to a table whose rows follow some convention
# indicating 'depth', say '__' hapens to be the seperator.

# You wan't to access a particular element, but you know it only by its column
# name 'm__d__v__version'

name='m__d__v__version'

version = reduce(dict.get, name.split('__'), dbo)

assert version == 1

foo = reduce(dict.get, 'm__d__v__foo'.split('__'), dbo)

assert foo == None

It's quite common to encounter deeply nested dictionaries that follow a strict convention for mapping a long name to some leaf item in that dictionary. The case that inspired this snippet was a proprietary object to database record mapping scheme (There are unfortunately lots of them around). The column names contained '__' to indicate object nesting levels.

Beware, accessing a non existent leaf item returns None. python -c "print help(dict.get)" will tell you why this should be expected.

I understand GvR lists reduce amongst his python regrets. After I realised I could use it like this, I rather like it !

From http://www.python.org/doc/essays/ppt/regrets/PythonRegrets.pdf (2002 may be out of date)

reduce() - nobody uses it, few understand it - for loop is clearer, and usually faster

Created by Robin Bryce on Mon, 20 Mar 2006 (PSF)
Python recipes (4591)
Robin Bryce's recipes (1)

Required Modules

  • (none specified)

Other Information and Tasks