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!
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