Python lambda return syntax

Viewed 65

Need some help with this code, can't figure the lambda syntax right here:

def func(m,n):
   if m < n:
      return ____
   elif m==n:
      return ____
   else:
      return ____

input:

func(3,10)()()()()()()
func(3,7)()()()
func(4,4)()
func(10,5)()()
func(9,5)()()

output should be:

13
m==n
m==n
15
14

I've tried:

def func(m, n):
    if m < n:
        return lambda: func(m+1, n-1)
    elif m == n:
        return lambda: print("m == n")
    else:
        return lambda: print(n+m)

This function works without errors with main like that:

func(3,10)()()()()() # ()
func(3,7)()()()
func(4,4)()
func(10,5)() # ()
func(9,5)() # ()

There is a way to make it work with the commented brackets?

1 Answers

The problem is that your lambda returns None, and so when you try to call the return value (which is what happens when you do f()()) you're trying to call None.

If you want to be able to call the return value of a function, and call that return value, et cetera, an arbitrary number of times, lambda is not a great tool, because it can't return a reference to itself. An object that implements __call__ makes it fairly straightforward, though:

class InfiniteCallable:
    def __init__(self, msg = None):
        self.msg = msg

    def __call__(self):
        if self.msg is not None:
            print(self.msg)
            self.msg = None
        return self

def func(m,n):
   if m < n:
      return InfiniteCallable(m+n)
   elif m==n:
      return InfiniteCallable("m == n")
   else:
      return func(n, m)

Note that InfiniteCallable.__call__(self) returns self, meaning that every time you call an InfiniteCallable it returns a reference to itself, which you can therefore call again, repeating that process an infinite number of times. The self.msg attribute allows it to print the message on the first call but not on each repeated call.

Related