[SciPy-User] Avoiding lambda functions

Zachary Pincus zachary.pincus at yale.edu
Mon Oct 18 14:35:53 EDT 2010


> from numpy import exp, indices  # numpy package from scipy.org
> img0 = imread('Lena.pgm')    # a 200 by 200 greyscale image
> shape = img0.shape           # (200, 200)
>
> def gauss(i,j,sigma,shape):  # a 2D gaussian function
>    x = -1.0 + 2.0*i/shape[0]
>    y = -1.0 + 2.0*j/shape[1]
>    ans = exp(-(x*x+y*y)/(2*sigma*sigma))
>    return ans
>
> def gaussianfilter(sigma,shape):
>    iray, jray = indices(shape)     # indices for a 200 x 200 array
>    filter = (lambda i,j: gauss(i,j,sigma,shape))(iray, jray)
>    return filter
>
> filter = gaussianfilter(0.1,shape)

Here you are constructing a lambda function and immediately calling  
it, storing the result (a numpy array) in the variable 'filter'.
Let's take that line apart a little. The below is equivalent:
temp_function = lambda i, j: gauss(i, j, sigma, shape)
filter = temp_function(iray, jray)

Which, as you can see now, is a little silly, as it is EXACTLY  
equivalent to the following:
filter = gauss(iray, jray, sigma, shape)

> def gaussianfilter01(sigma, shape):
>    iray,jray  = indices(shape)
>    def filter(i, j):
>        return gauss(i,j,sigma,shape)(iray, jray)
>    return filter

> This doesn't work!!
Yes, this will not work for a variety of reasons. It returns a  
function, as you have noted. Moreover, the function is broken. If I do  
the following:
filter = gaussianfilter01(sigma, shape)
then filter is a 2-parameter function that I can call as:
filter(i, j)
which will do two operations, that decompose as follows:
temp_result = gauss(i, j, sigma, shape)
(using the i and j passed to the filter function, and the "stored"  
sigma and shape value that was passed to gaussianfilter01.)
then it will attempt to call, as a function, temp_result as follows:
temp_result(iray, jray)
Which might work if temp_result (what gets returned from gauss) is a  
function, but of course it's not, it's a numpy array.

If you wanted to de-lambdafy the above code, this would be exactly  
equivalent:
def gaussianfilter01(sigma, shape):
    iray,jray  = indices(shape)
    def temp_function(i, j):
        return gauss(i,j,sigma,shape)
    filter = temp_function(iray, jray)
    return filter

Which is still silly compared to just calling gauss() directly.

Meta-lesson here: when confronted with something that doesn't work as  
expected in python, it is a good idea to pull apart compound  
statements in the interactive python interpreter to make sure that the  
intermediate results are what you are expecting.

Zach




More information about the SciPy-User mailing list