Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How does the functools cmp_to_key function works in Python?
Python's functools.cmp_to_key function is a utility that converts comparison functions into key functions for sorting. This is particularly useful when you need custom sorting logic that goes beyond simple attribute-based sorting.
What is functools.cmp_to_key?
The cmp_to_key function bridges the gap between old-style comparison functions and modern key-based sorting. A comparison function takes two arguments and returns:
- Negative value if first argument is "less than" the second
- Zero if both arguments are "equal"
- Positive value if first argument is "greater than" the second
Python's built-in sorting functions like sorted() expect key functions, not comparison functions. The cmp_to_key function converts your comparison logic into a compatible key function.
Syntax
from functools import cmp_to_key key_function = cmp_to_key(comparison_function) sorted_list = sorted(iterable, key=key_function)
Basic Example
Here's how to sort strings by length using a comparison function ?
from functools import cmp_to_key
def compare_lengths(str1, str2):
if len(str1) < len(str2):
return -1
elif len(str1) > len(str2):
return 1
else:
return 0
names = ['Alice', 'Bob', 'Charlie', 'Dave']
# Convert comparison function to key function
key_function = cmp_to_key(compare_lengths)
sorted_names = sorted(names, key=key_function)
print("Original:", names)
print("Sorted by length:", sorted_names)
Original: ['Alice', 'Bob', 'Charlie', 'Dave'] Sorted by length: ['Bob', 'Dave', 'Alice', 'Charlie']
Complex Sorting Example
Let's sort students by grade first, then by name for ties ?
from functools import cmp_to_key
def compare_students(student1, student2):
# Compare by grade first (higher grade comes first)
if student1['grade'] > student2['grade']:
return -1
elif student1['grade'] < student2['grade']:
return 1
else:
# If grades are equal, compare by name alphabetically
if student1['name'] < student2['name']:
return -1
elif student1['name'] > student2['name']:
return 1
else:
return 0
students = [
{'name': 'Alice', 'grade': 85},
{'name': 'Bob', 'grade': 92},
{'name': 'Charlie', 'grade': 85},
{'name': 'Dave', 'grade': 78}
]
sorted_students = sorted(students, key=cmp_to_key(compare_students))
for student in sorted_students:
print(f"{student['name']}: {student['grade']}")
Bob: 92 Alice: 85 Charlie: 85 Dave: 78
How It Works Internally
The cmp_to_key function creates a wrapper class that implements comparison operators. Here's a simplified version of what happens ?
from functools import cmp_to_key
# Simple comparison function
def compare_numbers(a, b):
return a - b
# Convert to key function
key_func = cmp_to_key(compare_numbers)
# Use with sorting
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
sorted_numbers = sorted(numbers, key=key_func)
print("Original:", numbers)
print("Sorted:", sorted_numbers)
Original: [3, 1, 4, 1, 5, 9, 2, 6] Sorted: [1, 1, 2, 3, 4, 5, 6, 9]
Comparison vs Key Function
| Aspect | Comparison Function | Key Function |
|---|---|---|
| Arguments | Two items to compare | Single item to extract key |
| Return Value | -1, 0, or 1 | Any comparable value |
| Performance | O(n log n) comparisons | O(n) key extractions |
| Complexity | Can handle complex logic | Simpler for basic sorting |
When to Use cmp_to_key
Use cmp_to_key when you need:
- Multi-criteria sorting with custom precedence
- Complex comparison logic that can't be expressed as a simple key
- Converting legacy comparison-based code
- Sorting based on relationships between items rather than individual attributes
Conclusion
The functools.cmp_to_key function enables complex custom sorting by converting comparison functions into key functions. Use it when you need sophisticated sorting logic that goes beyond simple attribute-based comparisons.
