The Python Lambda

Posted by Mike on July 19th, 2010 filed in Cross-Platform, Python

When I first started learning Python, one of the most confusing concepts to get my head around was the lambda statement. I’m sure other new programmers get confused by it as well and some of you are probably wondering what I’m talking about. So, in the spirit of education, let’s have a pop quiz:

Q. What is a lambda?

A. the 11th letter of the Greek alphabet
B. the craniometric point at the junction of the sagittal and lamboid sutures of the skull
C. the driver in an Arm Slave mecha that allows it to change the user’s thoughts into reality
D. the name of a series of Japanese rocket
E. anonymous (unbound) functions

If you guessed, F – all of the above, you got it right! Of course, in the context of this article, “E” is really the right answer. The Python lambda statement is an anonymous or unbound function and a pretty limited function at that. Let’s take a look at a few typical examples and see if we can find a use case for it.

The typical examples that one normally sees for teaching the lambda is some kind of boring doubling function. Just to be contrary, our simple example will show how to find the square root. First we’ll show a normal function and then the lambda equivalent:

import math
 
#----------------------------------------------------------------------
def sqroot(x):
    """
    Finds the square root of the number passed in
    """
    return math.sqrt(x)
 
square_rt = lambda x: math.sqrt(x)

If you try each of these functions, you’ll end up with a float. Here are a couple examples:


>>> sqroot(49)
7.0
>>> square_rt(64)
8.0

Pretty slick, right? But where would we actually use a lambda in real life? Maybe a calculator program? Well, that would work, but it’s a pretty limited application for a builtin of Python! One of the major pieces of Python that lambda examples are applied to regularly are Tkinter callbacks. We’ll take a look at that, but we’ll also take that information and try it with wxPython to see if works there just as well.

Tkinter + lambda

We’ll start with Tkinter since it’s included with the standard Python package. Here’s a really simple script with three buttons, two of which are bound to their event handler using a lambda:

import Tkinter as tk
 
########################################################################
class App:
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        frame = tk.Frame(parent)
        frame.pack()
 
        btn22 = tk.Button(frame, text="22", command=lambda: self.printNum(22))
        btn22.pack(side=tk.LEFT)
        btn44 = tk.Button(frame, text="44", command=lambda: self.printNum(44))
        btn44.pack(side=tk.LEFT)
 
        quitBtn = tk.Button(frame, text="QUIT", fg="red", command=frame.quit)
        quitBtn.pack(side=tk.LEFT)
 
 
    #----------------------------------------------------------------------
    def printNum(self, num):
        """"""
        print "You pressed the %s button" % num
 
if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()

Notice the btn22 and btn44 variables. This is where the action is. We create a tk.Button instance here and bind to our printNum method in one fell swoop. The lambda is assigned to the button’s command parameter. What this means is that we’re creating a one-off function for the command, much like in the quit button where we call the frame’s quit method. The difference here is that this particular lambda is a method that calls another method and passes the latter an integer. In the printNum method, we print to stdout which button was pressed by using the information that was passed to it from the lambda function. Did you follow all that? If so, we can continue…if not, re-read this paragraph as many times as necessary until the information sinks in or you go crazy, whichever comes first.

wxPython + lambda

Our wxPython example is pretty similar to the Tkinter one, only a little more verbose:

import wx
 
########################################################################
class DemoFrame(wx.Frame):
    """
    Frame that holds all other widgets
    """
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""        
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "wx lambda tutorial",
                          size=(600,400)
                          )
        panel = wx.Panel(self)
 
        button8 = wx.Button(panel, label="8")
        button8.Bind(wx.EVT_BUTTON, lambda evt, name=button8.GetLabel(): self.onButton(evt, name))
        button10 = wx.Button(panel, label="10")
        button10.Bind(wx.EVT_BUTTON, lambda evt, name=button10.GetLabel(): self.onButton(evt, name))
 
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(button8, 0, wx.ALL, 5)
        sizer.Add(button10, 0, wx.ALL, 5)
        panel.SetSizer(sizer)
 
    #----------------------------------------------------------------------
    def onButton(self, event, buttonLabel):
        """"""
        print "You pressed the %s button!" % buttonLabel
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = DemoFrame().Show()
    app.MainLoop()

In this case, we create a two-parameter anonymous function with the lambda statement. The first parameter is evt and the second is the button’s label. These are passed on to the onButton event handler, which is called when the user clicks on one of the two buttons. This example also prints the button’s label to stdout.

Wrapping Up

The lambda statement is used in all kinds of other projects as well. If you Google a Python project name and lambda, you can find lots of live code out there. For example, if you search for “django lambda”, you’ll find out that django has a modelformset factory that utilizes lambdas. The Elixir plugin for SqlAlchemy also uses lambdas. Keep your eyes open and you’ll be surprised how many times you’ll stumble across this handy little function maker.

Further Reading

Print Friendly

  • http://dougalmatthews.com/ Dougal Matthews

    A nice example of the lambda statement is the python sorted() built in where you can provide a lambda to sort an itteratable.

    For example, to sort a list of objects with the property last_name

    sorted(list, key=lambda i: i.last_name)

  • driscollis

    Hi Dougal,

    I don't know how I missed that one. Thanks for the heads-up!

    – Mike

  • http://dougalmatthews.com/ Dougal Matthews

    Very true – they are also faster. Perhaps not the best example but I couldn't think of another one off the top of my head :)

  • vvl

    Not to forget lambda's use in functional programming, e.g. having a function return another function:

    def make_incrementor(n): return lambda(x): x + n

    which produces a function that increments its argument by n. Not the most usual application but some things can be done very beautifully with this.

  • driscollis

    I almost mentioned that, but thought it might make the article rather confusing.

    – Mike

  • http://ryanbalfanz.net/ Ryan

    Good read, you might want to take a look at my post as well: http://blog.ryanbalfanz.net/?p=235

  • http://theglenbot.com Glenbot

    Good post. I wish lambda was as flexible as anonymous functions in JavaScript. One great use of lambda in Django is in the permission_required decorator.