[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