1

I have been struggling with a piece of python code that i can not make sense of. It's about a nested lambda function that looks like this:

lambda l: lambda x: x[0] in [None if not i.object else i.object.key for i in l]

I have tried to translate it and i came up with this but i do not think this is right

 def f1(l):
     def f2(x):
           for i in l:
               if not i.object:
                  return None
               else
                  return x[0]
user3253067
  • 113
  • 2
  • 11
  • The translation is quite simple. If you have `lambda : ` you have to replace it with `def name(`. In the case where `body` is an other `lambda`, since you can't do `return def name ...` you just change it to: `def name2...; return name2`. – Bakuriu Aug 23 '16 at 10:43

2 Answers2

2

Step 1:

def f1(l):
    def f2(x):
        xs = [None if not i.object else i.object.key for i in l]
        return x[0] in xs
    return f2

Step 2:

def f1(l):
    def f2(x):
        xs = []
        for i in l:
            if not i.object:
                xs.append(None)
            else:
                xs.append(i.object.key)
        return x[0] in xs
    return f2
citaret
  • 416
  • 4
  • 11
  • This is wrong. `lambda`s return the value of their body. In this case the outer lambda returns the inner lambda, but these functions do not return any function... You should have `return f2` at the end of the definition of `f1`. – Bakuriu Aug 23 '16 at 10:42
1

The accepted answer from @citaret is fine but one aspect of this hasn't been made clear so far and that is - why is it we have a function in a function, why not just have f1(l, x)?

The answer is that the function is likely used as an input to another function which takes exactly 1 argument and therefore we wish to 'capture' the list l in the function so we need only supply x when we invoke the function (this is referred to as a 'closure').

So for example we can create a function f which takes a list l as input and returns a new function (a closure) over l which accepts x and return True if x is in l:

f = lambda l: lambda x: x in l

We can then create a function f2 which is a closure over a list:

f2 = f([1, 2, 3])

Now we can map f2 to another list:

print map(f2, [2, 3, 4])

Produces:

[True, True, False]

Python's functools module provides a partial function to help with this and perhaps make the intent of the inner lambda clearer, i.e. we could define f3 as:

f3 = functools.partial(lambda l, x: x in l, [1, 2, 3])
print map(f3, [2, 3, 4])

For a more comprehensive description of closures see this answer.

Community
  • 1
  • 1
FujiApple
  • 796
  • 5
  • 16