Learning Python is a never-ending journey. One example of learning something new that helps in some situations is Lambda expressions. Lambda expressions, also known as anonymous functions, help in situations where you have a short single-line function that you want to consolidate.
For example, let’s say you wanted to build a Python function that prepares a show run
command to be sent to a device, but filters it based on an input. You might want to find a particular IP address, interface, or something else. The code is very focused and simple:
def show_run_filter(filter_string):
return ("show running-configuration | include {}".format(filter_string))
The function plugged into a Python interactive interpreter would look like this:
>>> def show_run_filter(filter_string):
... return ("show running-configuration | include {}".format(filter_string))
...
>>>
>>> show_run_filter("10.10.10.20")
'show running-configuration | include 10.10.10.20'
>>>
If you converted this function to a Lambda expression, it would look like this:
lambda filter_string: ("show running-configuration | include {}".format(filter_string))
We are using all the same pieces as before, but just a stripped-down syntax into one line for the anonymous function. The input parameter is filter_string
; the :
tells Python that everything after is the return expression, ("show running-configuration | include {}".format(filter_string))
. You cannot use Lambda expressions for multiline functions; they are often inline with other code.
Because lambda
is not the name of the function, how and what do we call it?
The easiest way is to give it a name and assign it to a variable.
show_run_filter_lambda = lambda filter_string: ("show running-configuration | include {}".format(filter_string))
To see the code executed, you call the function using the variable name that you assigned to it.
>>> show_run_filter_lambda = lambda filter_string: ("show running-configuration | include {}".format(filter_string))
>>>
>>> show_run_filter_lambda("10.10.10.30")
'show running-configuration | include 10.10.10.30'
>>>
Even though Lambda expressions can be useful in simply shortening the lines of code, they can also help in other situations. For example, you can use Lambda expressions to pass a function as an argument in another function.
When are there situations where you want to pass a function as an argument?
One such situation is when you want to sort a list of items. Python has a built-in function called sorted()
that can accomplish this task. The sorted()
function takes two arguments, iterable
and key
. The iterable
is the list of items you want to sort. The key
parameter takes a function as an input, which is called upon to determine how to sort the list.
First, let’s look at a simple example using the sorted()
function. Let’s say you have a list of numbers and you want to sort them. Here’s an example where you can use the sorted()
function to do this:
>>> numbers = [1, 5, 3, 2, 4]
>>> sorted(numbers)
[1, 2, 3, 4, 5]
>>>
Now, let’s see it with a Lambda expression, using that anonymous function as input to sort just the odd numbers:
>>> numbers = [1, 5, 3, 6, 2, 4]
>>> sorted(numbers, key=lambda x: x % 2)
[6, 2, 4, 1, 5, 3]
>>>
The key
parameter took our Lambda expression as a function input, where we told it to sort the list based on the remainder of the number divided by 2. This is a simple example, but it shows how you can use Lambda expressions to sort a list of items.
Taking that same concept but now applying it to networking, we can use sorted
to help us audit our network device’s software versions. Let’s say you have a list of boot statements from the running-configuration backups of network devices. You want to determine if they need software upgrades by looking at the OS version and platform. They are in a list, and you want to sort them by whether they are old or meet the current standard.
You can use the sorted()
function to do this with a Lambda expression—assuming you gather the boot statements from the network devices and then put them into a list of boot statements.
For the sake of simplicity, we are just using a list, but in reality, it would be a list of dictionaries to keep track of which device has which boot statement.
os_audit = [
"asr1000rp1-adventerprisek9.03.15.04.S.155-1.S1-std.bin",
"asr1000rp1-adventerprisek9.03.14.01.S.155-1.S1-std.bin",
"asr1000rp1-adventerprisek9.03.16.01.S.155-1.S1-std.bin"
]
You can use the sorted()
function to sort the list of boot statements by the OS version. We will use a Lambda expression to do this by splitting the string on the .
and then using the third element in the list as the key to sort by (because in this case, only the minor revision is different between versions).
The Lambda expression will look like this:
lambda x: x.split(".")[2]
sorted(os_audit, key=lambda x: x.split(".")[2])
When you run the sorted
function, you will get the following output:
>>> sorted(os_audit, key=lambda x: x.split(".")[2])
['asr1000rp1-adventerprisek9.03.14.01.S.155-1.S1-std.bin', 'asr1000rp1-adventerprisek9.03.15.04.S.155-1.S1-std.bin', 'asr1000rp1-adventerprisek9.03.16.01.S.155-1.S1-std.bin']
>>>
Now we have the sorted list and can prioritize which devices need an upgrade. Even though this example was a bit contrived, you can see that using a Lambda expression saved us lines of code and in the context of a larger project could help readability quite a bit, in addition to saving time.
Congrats on finishing this tutorial! Check out the following links to learn more about Python and network automation.