For example, if I have a Person
class
class Person:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def __repr__(self) -> str:
return f"({self.name}, {self.age})"
and a List of Person
persons = [
Person("Bob", 25),
Person("Alice", 25),
Person("Charlie", 23),
Person("Dave", 25),
]
I can sort the list by age
in ascending order, and in case of a tie, sort by name
in ascending order using the following method:
sorted_persons = sorted(persons, key=lambda p: (p.age, p.name))
Question:
However, I'm looking for a way to sort the list by age
in ascending order and, in the event of a tie in age, sort by name
in descending order. How could I achieve this in Python?
I've come up with one solution, as shown below, but it seems a bit inelegant. Is there a more succinct way to write a string comparison method that can handle all three cases (i.e., less than, equal to, and greater than)? For instance, Java has a s1.compareTo(s2)
method that makes such comparisons straightforward.
Here's the solution I'm currently working with:
from functools import cmp_to_key
def compare(p1, p2):
cmp = p1.age - p2.age
if cmp != 0:
return cmp
if p1.name < p2.name:
return 1
elif p1.name > p2.name:
return -1
return 0
sorted_persons = sorted(persons, key=cmp_to_key(compare))
This code correctly sorts the persons
list first by age
in ascending order, and then by name
in descending order when the ages are equal. However, I feel there should be a cleaner, more Pythonic way to handle this. Any suggestions?