Chapter 5: Lambda functions

Lambda in sorted()

face Josiah Wang

Here is another practical use case. Say you have a dictionary containing word frequencies. And you would like to sort the words by their frequencies (descending order). You can use lambda function to sort the items by the values of the dictionary.

This time, we will use the sorted() function rather than the mutable list.sort(). Just because we can!

freq = {"python": 24, "cat": 78, "mat": 12, "aardvark": 1, "fish": 56}
sorted_tuples = sorted(freq.items(), key=lambda x:x[1], reverse=True)
print(sorted_tuples)
## [('cat', 78), ('fish', 56), ('python', 24), ('mat', 12), ('aardvark', 1)]

Now, let’s say there are two words with the same frequency. To break the tie, we would like to sort by the word (ascending). Here is a solution that makes use of tuples as expressions. Note the trick of using the negative -x[1] for sorting the frequency in a descending order.

freq = {"snake": 24, "python": 24, "cat": 78, "mat": 12, "mac": 12, "fish": 56}
sorted_tuples = sorted(freq.items(), key=lambda x:(-x[1], x[0]))
print(sorted_tuples)
## [('cat', 78), ('fish', 56), ('python', 24), ('snake', 24), ('mac', 12), ('mat', 12)]

Exercise

Use the sorted() function and lambda functions to sort the singers by the total of number of characters in their first and last names combined (in ascending order). If the number of characters are the same (e.g. “Luther Vandross” and “Michael Jackson” both have 14 characters), sort by their first name. Again, you should only need one line to solve this.

singers = [("Michael", "Jackson"), ("Billy", "Joel"), ("Lionel", "Richie"), 
           ("Tina", "Turner"), ("Luther", "Vandross")]

sorted_singers = sorted(????)

assert sorted_singers == [('Billy', 'Joel'), 
                          ('Tina', 'Turner'),
                          ('Lionel', 'Richie'), 
                          ('Luther', 'Vandross'), 
                          ('Michael', 'Jackson')]

A possible solution. Sort first by the sum of the length of the two strings (len(x[0])+len(x[1])), and then if there is a tie sort by first name (x[0]).

singers = [("Michael", "Jackson"), ("Billy", "Joel"), ("Lionel", "Richie"), 
           ("Tina", "Turner"), ("Luther", "Vandross")]

sorted_singers = sorted(singers, key=lambda x: (len(x[0])+len(x[1]), x[0]))

assert sorted_singers == [('Billy', 'Joel'), 
                          ('Tina', 'Turner'),
                          ('Lionel', 'Richie'), 
                          ('Luther', 'Vandross'), 
                          ('Michael', 'Jackson')]