Hands-On Reactive Programming with Python
上QQ阅读APP看书,第一时间看更新

Lambdas

Lambdas were introduced in the code sample of Chapter 1, An Introduction to Reactive Programming. They are heavily used with ReactiveX. More than that, the availability of lambdas is one of the key features that makes ReactiveX code easy to write and read. A lambda is a single-expression anonymous function. It behaves just like a function and must contain only one expression. A lambda is declared with the keyword lambda. Lambdas are very useful when a short function has to be provided to another function or a variable. In such cases, when the function to be provided is a one-liner, using lambda is easier because it avoids declaring many functions.

Here is a simple example of the usage of lambda:

def exec(f, value):
f(value)

def title(value):
print(value.title())

exec(title, "Hello world")
exec(lambda i: print(i.upper()), "Hello world")
exec(lambda i: print(i.lower()), "Hello world")

The exec function takes a function (f) and value as input parameters, and then executes the f function with value as a unique argument. In the example, the exec function is first called with a named function as an argument, the title function. The title function takes a string as a parameter and prints it in title case. This works perfectly, but it requires some boilerplate code just to print a statement.

The last two calls of the exec function use lambda instead of a function. The first call prints the string in upper case and the latter prints the string in lower case. In these two examples, there is no need to declare two other functions. The provided function object is declared inline as an input argument. There is less code to write, and reading the code is easier because the text follows the code logic. Run this example to get the following output:

Hello World
HELLO WORLD
hello world

With ReactiveX code, lambdas are heavily used because many small operations are chained together. Consider this other example:

from rx import Observable

a = Observable.from_(["Hello", "Goodbye"]) \
.map(lambda i: i + " the") \
.map(lambda i: i + " world") \
.map(lambda i: i.upper())

a.subscribe(lambda i: print(i))

Here, three actions are done on each item of Observable:

  • Appending the the word
  • Appending the world word
  • Converting the whole as upper case

These three actions are trivial, so writing a dedicated function for each of them is a waste of time, space, and readability. Also, since the subscription action is also trivial, lambda can also be used here. The result of this code sample is the following one:

HELLO THE WORLD
GOODBYE THE WORLD

Each item of Observable went through the three operations before being printed, and using lambda made the code smaller and easier to read.