"""
Functionality copied from the toolz package to avoid having
to add toolz as a dependency .
See https : / / github . com / pytoolz / toolz / .
toolz is released under BSD licence . Below is the licence text
from toolz as it appeared when copying the code .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright ( c ) 2013 Matthew Rocklin
All rights reserved .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are met :
a . Redistributions of source code must retain the above copyright notice ,
this list of conditions and the following disclaimer .
b . Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
c . Neither the name of toolz nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE .
"""
import operator
from functools import reduce
def get_in ( keys , coll , default = None , no_default = False ) :
"""
NB : This is a straight copy of the get_in implementation found in
the toolz library ( https : / / github . com / pytoolz / toolz / ) . It works
with persistent data structures as well as the corresponding
datastructures from the stdlib .
Returns coll [ i0 ] [ i1 ] . . . [ iX ] where [ i0 , i1 , . . . , iX ] == keys .
If coll [ i0 ] [ i1 ] . . . [ iX ] cannot be found , returns ` ` default ` ` , unless
` ` no_default ` ` is specified , then it raises KeyError or IndexError .
` ` get_in ` ` is a generalization of ` ` operator . getitem ` ` for nested data
structures such as dictionaries and lists .
>> > from pyrsistent import freeze
>> > transaction = freeze ( { ' name ' : ' Alice ' ,
. . . ' purchase ' : { ' items ' : [ ' Apple ' , ' Orange ' ] ,
. . . ' costs ' : [ 0.50 , 1.25 ] } ,
. . . ' credit card ' : ' 5555-1234-1234-1234 ' } )
>> > get_in ( [ ' purchase ' , ' items ' , 0 ] , transaction )
' Apple '
>> > get_in ( [ ' name ' ] , transaction )
' Alice '
>> > get_in ( [ ' purchase ' , ' total ' ] , transaction )
>> > get_in ( [ ' purchase ' , ' items ' , ' apple ' ] , transaction )
>> > get_in ( [ ' purchase ' , ' items ' , 10 ] , transaction )
>> > get_in ( [ ' purchase ' , ' total ' ] , transaction , 0 )
0
>> > get_in ( [ ' y ' ] , { } , no_default = True )
Traceback ( most recent call last ) :
. . .
KeyError : ' y '
"""
try :
return reduce ( operator . getitem , keys , coll )
except ( KeyError , IndexError , TypeError ) :
if no_default :
raise
return default