In the 1930s, mathematicians began to solve the problem of resolution—Entscheidungsproblem— which was first formulated by David Hilbert. The crux of the problem’s solution is the formal language the statement needs to be written in. The problem’s solution needs to prove the existence of an algorithm that determines a statement’s truth or falsity in a finite number of steps.
The answer was found by the great scientists of the time. Alonzo Church and Alan Turing showed the Entscheidungsproblem problem was generally unsolvable, as proved by Church with the help of the λ-calculus he invented in the mid-1930s and by Turing’s machine he created.
The modern Python language, which is now widely used in information systems development, machine learning, and system administration, also supports the use of lambda calculus.
Let's see how the lambda calculus works in Python and where it is appropriate to use this construction.
A simple example of Lambda in Python
Generally speaking, all lambda expressions in Python must have the following composition:
lambda arguments : expression
Code language: JavaScript (javascript)
Here, lambda is a keyword, arguments can be one or several arguments, and the expression is some action to perform and return results to the upper code.
Let’s take a look at this classical example in Python:
import unittest
def add_func(x, y):
return x + y
class TestFunction(unittest.TestCase):
def test_func(self):
self.assertEqual(add_func(2,3), 5)
if __name__ == '__main__':
unittest.main()
In this example, the function add_functhat accepts two arguments (2 and 3) and adds them together. As shown in unit tests, there are 5 as a successful sum of two given arguments.
Ran 1 test in 0.000s
OK
Code language: CSS (css)
How will this function work with lambda expression? The code is very simple.
This example uses sum = lambda x, y : x+y as the lambda expression instead of the function add_func(). To call this lambda, you can use sum(2,3). The result is the same as shown on the unit tests.
Ran 2 tests in 0.000s
OK
Code language: CSS (css)
Just in case, we’ll mention the type of lambda expression object type(sum) which will return <class 'function'>.
PEP8 recommendation
Please consider that Python’s style guide, PEP8, highly recommends that the use case def add_func() has a clear code understanding and readability.
As mentioned in PEP8, “Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier:
# Correct:
def f(x): return 2*x
# Wrong:
f = lambda x: 2*x
Code language: PHP (php)
The first form means that the name of the resulting function object is specifically 'f' instead of the generic '<lambda>'. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)”.
At the same time, the lambda expression is helpful in some parts of your code and will be understood very well.
Why use Lambda in Python
map
map() is a very familiar function in Python and it’s very helpful; for example, if you need to perform an action on every element, but do not use the cycle, lille for or while. Please take a look at its manual here.
map(function_object, iterable1, iterable2,...)
Where function_object is the object for function and iterable1, 2, is a set of iterable elements.
list(map(lambda x : x*2, [1, 2, 3, 4, 5]))
Code language: CSS (css)
It will return a list:
[2, 4, 6, 8, 10]
Code language: JSON / JSON with Comments (json)
Here, we use lambda x : x*2 as an anonymous function that makes syntax very compact, avoids defining the new function, and gives a clear understanding for everybody. The function list() is necessary because it returns a map object, so it will create a list from the iterator.
filter
As well as map, the filer() function is a great example of how to express your idea in Python in a very compact and clear form. You can look at its description here.
Let’s find all numbers that are a fraction of 10.
numbers = [1, 20, 3, 40, 5, 60, 100]
result = filter(lambda x: x % 10 == 0, numbers)
print (list(result))
Code language: PHP (php)
Will return:
[20, 40, 60, 100]
Code language: JSON / JSON with Comments (json)
Please consider that filter() constructs an iterator. To get a list from the iterator, you need to use something like list (result).
In addition, it’s important to mention that list comprehension can be effectively used for many tasks. This allows you to do many helpful actions on a list without the for instruction. Please refer to this article for more details.
reduce
The function functools.reduce() is a great example where the lambda expression is effectively used. Please take a look at its description here.
import functools
result = functools.reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print (result)
Code language: JavaScript (javascript)
This will calculate the sum of the sequence ((((1+1)+2)+3)+5) and, in our case, will return 15 as a result.
Another great well-known example from many internet sources is the calculation of Fibonacci numbers:
fib = lambda n: functools.reduce(lambda x, _: x + [x[-1] + x[-2]],
range(n - 2), [0, 1])
print (fib (10))
Code language: PHP (php)
This will produce a list of Fibonacci numbers:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Code language: JSON / JSON with Comments (json)
While it’s not simple to understand, it works very well. This lambda expression returns a list and the list starts from 0 and 1. Then, every next element is computed like xn = xn-1 + xn-2. This calculation repeats n-2 times.
In this example, reduce() accepts three parameters functools.reduce(function, iterable[, initializer]).
Where:
- function is lambda x, _: x + [x[-1] + x[-2]] i.e. xn = xn-1 + xn-2
- iterable is range(n-2) because we don’t need to calculate elements 0 and 1 in the Fibonacci sequence
- initialiser is [0, 1], i.e. is the start sequence of the Fibonacci number.
This interesting example uses two lambda expressions at the same time. It works fast, at least with the same speed as Python code without lambda.
sorted
Another great example of using lambda is sorted(). You can find a classical example from this manual.
class Student:
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
student_objects = [
Student('john', 'A', 15),
Student('jane', 'B', 12),
Student('dave', 'B', 10),
]
sorted(student_objects, key=lambda student: student.age) # sort by age
We will have the following output:
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Code language: JSON / JSON with Comments (json)
The magic of using lambda is providing a comparison function lambda student: student.age.
Another great example of using lambda is the as __lt__() function which can be given directly to the Student object:
Student.__lt__ = lambda self, other: self.age < other.age
sorted(student_objects)
Code language: PHP (php)
It will give the following output:
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Code language: JSON / JSON with Comments (json)
This example shows how to use lambda effectively in Python.
Conclusion
Many Python developers from Svitla Systems recommend lambda as a very helpful element for real tasks in programming. With that being said, lambda needs to be used very carefully, according to the PEP8 recommendation.
If you’d like to learn more about using lambda in Python, please refer to this article from Real Python by Andre Burgaud where you’ll understand more about:
- Arguments
- Decorators
- Closure
- Evaluation Time
- Monkey Patching
Many programming languages now support lambda. Some of the languages use this concept very intensively. For one, the Python language supports very rich possibilities to use lambda but the code needs to be clear, easy to read, and reasonable. Many new developers overuse lambda in Python, but this code should be replaced with def functions.
Our experienced Python developers and data scientists from Svitla Systems have a great level of understanding and practical expertise in creating large projects with different Python frameworks. If you need to develop your project on Python from scratch or rebuild an existing project, please contact Svitla Systems representatives in your area.