Something that works on arbitrarily nested lists, e.g. [[1,2],[[5]],[7,[8,[9,11]]]] :
def apply_f(a,f):
if isinstance(a,list):
return map(lambda t:apply_f(t,f), a)
else:
return f(a)
here is an example of running this:
>>> ll=[[1,2],[[5]],[7,[8,[9,11]]]]
>>> apply_f(ll,lambda t:t**2)
[[1, 4], [[25]], [49, [64, [81, 121]]]]
and here is how to do the same only on selected levels:
def apply_f(a,f,depth,levels):
if isinstance(a,list):
return map(lambda t:apply_f(t,f,depth+1,levels), a)
else:
if depth in levels:
return f(a)
else:
return a
getting e.g.
>>> apply_f(ll,lambda t:t**2, 0, [2,4])
[[1, 4], [[5]], [49, [8, [81, 121]]]]
there are some optimisations to do here, by avoiding passing f
and levels
around (making the recursive function an inner function in a wrapper,
so that it can use f
and levels
from the outer scope), but that's minor. (Note that this is Python 2, for Python 3 you need to replace map
with something else).
For a more generic input, the following would do the trick:
def apply_f(a,f):
try:
return(f(a))
except:
return map(lambda t:apply_f(t,f), a)
So now also the following sort of works:
>> apply_f([(1,2),[[5]],[7,(8,[9,11])]],lambda t:t**2)
[[1, 4], [[25]], [49, [64, [81, 121]]]]
(things get slightly rewritten, as map()
always produces lists...)