pythonscipyhermite

List of scipy hermite polynomials behave unexpectedly when used as lambda functions


I want to build a container of Hermite polynomials (link to scipy's hermite doc) of different orders. From what the doc says, I expect scipy.special.hermite to accept the order n and return a function - an Hermite polynomial of order n.

This seems to work fine with single functions. But when I try to use a list of Hermitte polynomials by realising them as lambda functions, it seems they will all be reset to the last polynomial:

from scipy.special import hermite
base_funcs = [lambda x: hermite(i)(x) for i in range(5)]

[f(1) for f in base_funcs]
Out[40]: [-20.0, -20.0, -20.0, -20.0, -20.0]
hermite(0)(1)
Out[41]: 1.0
hermite(4)(1)
Out[42]: -20.0

Is there a way to initiate a container of different Hermite polynomials properly, without previous elements being overwritten by subsequent ones in the container apprehension statement? Thanks!


Solution

  • As Warren's comment says, this is due to Python's late binding mechanism. To circumvent it, one solution is to include the loop variable as one of the function's default arguments. i.e.

    [lambda x, i=i: hermite(i)(x) for i in range(5)]
    

    Suggested reading: https://docs.python-guide.org/writing/gotchas/#late-binding-closures.