The two lambdas in f_new actually call the same function.
This is because the list is formed of lambdas that capture the fi
variable (at compile time) but do not actually execute the function. So, when the list runs through the generator ... for fi in f
the lambdas that are produce all use the captured variable fi
and end up with the same function pointer (i.e. the last one in f
)
You would need to consume the current value of fi in the comprehension in order to avoid this capture side effect:
f_new = [(lambda fn:lambda x: fn(x))(fi) for fi in f]
print( [fi(2) for fi in f_new] )
[4, 102]