How does the functools cmp_to_key function works?

Hello, Coders!! In this section, we will discuss the use of the functools module’s cmp_to_key function in Python.

cmp_to_key() function in Python

The cmp_to_key() function is a built-in function of functools library. It is used for comparing elements in a Python program. It basically returns a special key argument for this operation, and the argument is strictly callable. Furthermore, it is used along with the methods that use a key as parameters such as sorted(), min(), max(), etc.

Syntax:

functools.cmp_to_key(callable)

Use of Key parameter and cmp function in Python

You might wonder what a key is?  Well, a key is nothing but a parameter. In Python, the sorted() function takes key as an optional parameter for sorting the elements. The argument is callable, and it returns a value for comparing with other values when called.

In the older version of Python, instead of the key parameter, the cmp function was used. The cmp function returns -1 if the first element is less in value than the second element, +1 if the first element is greater, and 0 if the two elements have the same value from a set of two elements. This function is much simpler and easy to write than a key.

At some time, the cmp function was deprecated and wasn’t added in Python3. But we can use the cmp_to_key function, which is capable of converting a cmp function to a key. In this way, we can still use the cmp function in the latest version of Python.

You can also read the source code of cmp_to_key here for a better understanding:

def cmp_to_key(mycmp):
    class K(object):
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

Here we can see the cmp_to_key returns a K class that behaves like a key function. The class is callable and creates a new instance when called.

Let’s understand with an example program:

Program to sort a list using a key returned by cmp_to_key() function

Setp1: Import the functools library to the program.

import functools

Step2: Define a cmp function comparing two elements.

def mycmp(x, y):
    print("compare ", x, " with ", y)
    if x > y:
        return 1
    elif x < y:
        return -1
    else:
        return 0

Step3: Using the sorted() method, sort the list of elements with the key received by converting the cmp through the cmp_to_key() function.

print(sorted([2, 3, 7, 1], key=functools.cmp_to_key(mycmp)))

Here is the complete Python Program:

import functools

def mycmp(x, y): 
    print("compare ", x, " with ", y) 
    if x > y: 
        return 1 
    elif x < y: 
        return -1 
    else: 
        return 0
    
print(sorted([2, 3, 7, 1], key=functools.cmp_to_key(mycmp)))

Output:

compare  3  with  2
compare  7  with  3
compare  1  with  7
compare  1  with  3
compare  1  with  2
[1, 2, 3, 7]

Here, each element is compared with another element until we find a sorted list. Then mycmp() functions return  key using the cmp_to_key() after completion of the comparing operation. The sorted() function took the key as a parameter for sorting the elements in ascending order.

Hope you have enjoyed the explanation and learned the concept and use of cmp_to_key in Python.

Happy Coding!!

You can also read, How to install functools32 in Python

Leave a Reply

Your email address will not be published.