I am starting out on learning Python 3. I am wondering how to perform a custom sort. For instance, I might want to sort a list of animals in the following manner: sort by first character ascending, then by length descending, then by alphanumeric ascending.
A list made up of "ant", "antelope", "zebra", "anteater" when properly sorted would become "anteater", "antelope", "ant", "zebra".
I have read a little on the docs but don't quite get the "key" argument to the sort method. Any examples? PS: this isn't a College assignment question. I am just looking to play around with python a bit.
I learnt java a long, long time ago and might have implemented the custom sort something like the following:
import java.util.*;
public class sortDemo implements Comparator<String> {
public static void main(String[] args) {
ArrayList<String> animals = new ArrayList<String>();
animals.add("ant");
animals.add("antelope");
animals.add("zebra");
animals.add("anteater");
for (String a:animals){
System.out.println(a);
}
System.out.println();
// want output to be anteater, antelope, ant, zebra following the sort
Collections.sort(animals, new sortDemo());
for (String a:animals){
System.out.println(a);
}
}
public int compare(String s1, String s2) {
if (s1.charAt(0) > s2.charAt(0)){
return 1;
} else if (s1.charAt(0) == s2.charAt(0)){
if(s1.length() < s2.length()) {
return 1;
} else if (s1.length() == s2.length()) {
return s1.compareTo(s2);
} else {
return -1;
}
} else {
return -1;
}
}
}
In Python, we can write custom sort functions that work with sort() and sorted() . The value of the key parameter should be a function that takes a single argument and returns a key for sorting purposes.
To define custom sort function, you need to compare first value with second value. If first value is greater than the second value, return -1. If first value is less than the second value, return 1 otherwise return 0. The above process will sort the data in descending order.
Using sort(), lamba, index(): The sort() function does the required in-place sorting(without creating a separate list to store the sorted order) along with a lambda function with a key to specify the function execution for each pair of tuples, the index() function helps to get the order from our custom list list_2.
Python's default sort uses Tim Sort, which is a combination of both merge sort and insertion sort.
The sorting key is a function that, given a list element, returns a value that Python knows how to compare natively. For example, Python knows how to compare integers and strings.
Python can also compare tuples and lists that are composed of things it knows how to compare. The way tuples and lists get compared is that earlier items in the tuple or list take precedence over later values, just as you would expect.
In your case, you would want to make the following key function:
lambda name: (name[0], -len(name), name)
Items with smaller keys always come earlier in a sorted list. Thus, a smaller initial character causes an animal to come earlier. If two names have the same initial, a longer name length causes an animal to come earlier because the negative name length is smaller. Finally, if two animals' names have the same initial and the same length, the tie is broken by lexicographic order.
This program demonstrates how to sort a list with the above key function:
animals = ["ant", "antelope", "zebra", "anteater", "cod", "cat"]
animals.sort(key=lambda name: (name[0], -len(name), name))
print(animals)
The Python docs give excellent examples for .sort
and sorted()
That said:
animals = ["Anteater", "Aardvark", "Eagle", "Platypus"]
sorted(animals, key=lambda animal: animal[2])
['Platypus', 'Eagle', 'Aardvark', 'Anteater']
The key here is the third letter of each animals name. I made the third letter the key using a lambda function lambda: animal: animal[2]
. This lambda function allowed me to specify the third letter, because I couldn't just say key=animal[2]
, as animal would be undefined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With