Skip to content

Instantly share code, notes, and snippets.

@lukassup
Last active June 8, 2016 19:00
Show Gist options
  • Save lukassup/3a88dfc37f906a03a4a2 to your computer and use it in GitHub Desktop.
Save lukassup/3a88dfc37f906a03a4a2 to your computer and use it in GitHub Desktop.

Lambda functions in Python

Note: I use Python 3, but most of these should work in Python 2 too.

Intro

Lambda functions are also known as anonymous functions and are typically passed as arguments to other functions. Notable examples are the map(), reduce(), filter() built-in functions which require a function to be passed as an argument.

Lambda functions have a specific syntax in Python which is slightly shorter than the def function definition. The return statement is omitted in lamdas.

We can define a function which returns x if it is greater than zero or 0 if it's below zero in the regular def notation.

def myfun(x):
    if x > 0:
        return x
    else:
        return 0

Then call it two times.

myfun(-10)
0
myfun(5)
5

The exact same thing can be written with lambda functions. You can assign a lambda function to a variable and call it like any normal function.

mylambda = lambda x: x if x > 0 else 0
mylambda(-10)
0

Or you can define and call a lambda inline. The function is not reusable.

(lambda x: x if x > 0 else 0)(5)
5

map, reduce and filter

Lets say that we still have the myfun function from above defined and we want to try out the map(), reduce() and filter() functions.

We define the following list of integers for this example

arr = [-8, 4, 10, -6, 0, 8]

map() calls a function with each list element and stores results in a new list. In our case map() turned the negative numbers into zeroes.

list(map(myfun, arr))
[0, 0, 10, 0, 0, 8]

filter() calls a function for each argument and returns a list of elements for which the function returned True or non-zero values.

list(filter(myfun, arr))
[10, 8]

Note: map() returns a map object and filter() returns a filter object. You have to convert them to a list.

The reduce() function is slightly trickier. It requires a function that takes two arguments: first argument is the result of previous iteration and the second one is the current element. Once reduce() has done iterating over all items, it then returns the value of the first function argument. This example shows how to find the smallest number in a list with a lambda function.

Note: reduce() was removed from standard built-in functions in Python 3. You are still able to import it from functools.

from functools import reduce
reduce((lambda x, y: x if x < y else y), arr)
-8

A real example

Define an ask function which excpets a user to enter some input which can be parsed to a given variable type -- int, float, str or bool.

It also can take a function as parameter for filtering the input. See condition.

def ask(var_type=str, prompt=None, condition=lambda x: True):
    """
    Input parser for specific variable types

    :var_type: type, default: str
    :returns: {var_type}

    """
    
    var = None
    var_types = {
            int: "an integer",
            float: "a floating point number",
            str: "a string",
            bool: "anything for True, blank for False"
            }

    if not prompt:
        prompt = "Enter {0}: ".format(var_types.get(var_type, ""))

    while True:
        try:
            var = var_type(input(prompt))
            # The most important part!
            if condition(var): break
        except Exception as e:
            print("*** Error:", e)

    return var

The three examples show how to:

  1. Prompt user for an integer greater than 10.
  2. Prompt user for a float between -51 and -50.
  3. Prompt user for a string longer than 8 characters.
print(ask(int, prompt="Type an integer > 10: ",
    condition=lambda x: x > 10))

print(ask(float, prompt="Any decimal -51 <= x < -50: ",
    condition=lambda x: -51 <= x < -50))

print(ask(str, prompt="At least 8 characters: ",
    condition=lambda x: len(x) > 8))

Another example

Resolve symbolic permissions to their octal representation

from functools import reduce
from os import R_OK, W_OK, X_OK
from sys import argv

PERMS = { "r": R_OK, "w": W_OK, "x": X_OK, "-": 0, }

def sym_perms(perm_s):
    """Resolve symbolic permissions to octal from a 3 character string"""

    return reduce( (lambda x, y: x | y), map(PERMS.get, perm_s) )


def split_by(it, count):
    """Split an iterable into groups of N"""

    return [ it[n:n+count] for n in range(0, len(it), count) ]

def perms_from_string(perm_s):
    """Resolve user, group and world permissions to octal"""

    return "".join(map(
        (lambda x: str(sym_perms(x))),
        split_by(perm_s, 3)
        ))

if __name__ == "__main__":
    print(perms_from_string(argv[1]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment