It looks like your loop is just reimplementing what reduce
does. Here's a functional look at your function composition problem:
def compose1(fnlist):
if not fnlist:
return lambda x: x
# compose 1 function of x from two others
def compose2fns(fn1, fn2):
return lambda x : fn1(fn2(x))
# or if you really love lambdas
# compose2fns = lambda fn1,fn2: lambda x: fn1(fn2(x))
# use reduce to cumulatively apply compose2fns to the functions
# in the given list
return reduce(compose2fns, fnlist)
This passes your tests just fine.
CODE GOLF: I couldn't resist, here is a one-liner, even including your check for an empty input list:
compose1 = lambda fnlist: reduce(lambda fn1,fn2: lambda x : fn1(fn2(x)),
fnlist or [lambda x:x])