Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does this lambda for sorting numbers work?

#code for sorting big integers
lis = ['234', '5', '2', '12435645758']

lis.sort(key = lambda x: len(x))
print lis
#output ['5', '2', '234', '12435645758']

lis.sort(key = lambda x: (len(x), x))
print lis
#output ['2', '5', '234', '12435645758']

Am trying to sort big number strings in Python without converting the strings to integers and couldn't understand how these lambda expression are evaluated.

The first lambda expression is sorting based on length of string and sorting the list, but what does the second one do? I would like to know how the second lambda expression is evaluated.

like image 799
Manikanta Raju Avatar asked Oct 18 '22 11:10

Manikanta Raju


1 Answers

The lambda returns a tuple for each value in the list. Those tuples are then used to inform the sort order. So instead of comparing '234' with '5', the sort algorithm is asked to compare (3, '234') and (1, '5').

Python sorts tuples lexicographically, that is to say, by comparing the first elements of two tuples first, then if those are the same, moving on to compare the second elements, etc. until there are no elements left to compare.

Because the tuple holds both the length and the string itself, for strings of equal length the strings are next sorted on their actual value. This puts longer strings at the end, shorter strings at the front, and within each group of equal length, the strings are sorted by their value.

Looking at your input example again, for '234' and '5', the resulting tuples (3, '234') and (1, '5') have unequal first elements so (1, '5') is sorted before (3, '234'). But for '5' and '2', the resulting tuples are (1, '5') and (1, '2') (both are 1 character long), and the first elements of these tuples are equal. So they are sorted on the second element instead, putting '2' before '5'.

Without such tie breakers (so the keys being equal), Python leaves the relative order intact. For your first example, the sort key is merely len(x), and since '5' and '2' have the same length and there is nothing else to compare them by, Python puts them into the output in the same relative order, '5' before '2'.

like image 51
Martijn Pieters Avatar answered Oct 20 '22 11:10

Martijn Pieters