Kodeclik Blog
Python max() using lambda functions
Python iterables like lists, dictionaries, and strings allow you to traverse them and order them according to any reasonable criterion you might have.
For instance, let us take a Python dictionary denoting items in your school cafeteria and their respective prices:
menu_items = {
"Fries": 1.00,
"Apple": 0.25,
"Orange": 0.68,
"Mac n Cheese": 0.75,
"Pizza Slice": 0.80,
"Fresh Oven-baked Biscuits": 0.35
}
Note that every item in the dictionary is a (key, value) pair where key is the name of the menu item and price denotes the price of the menu item.
Let us try to find the max() in this collection. But what does max() mean in this context? Do we intend to sort the items alphabetically and pick the one with the largest key (hence the name that appears lexicographically the latest in order) or do we mean to pick the one with the highest price (and thus costliest)?
The nice thing about Python is that it allows you to choose whatever interpretation makes sense to you! You just have to create a lambda function that captures the meaning you have in mind.
Python max without lambda
Let us first try max() on the above iterable without any arguments and see what happens:
print(max(menu_items))
This yields:
Pizza Slice
As you can see a default max() on an iterable is run on the keys (in our case, the names of the menu items) and they are lexicographically ordered and thus the one that appears latest in the alphabet is returned, which is “Pizza Slice”.
If you desire to find the cost of the item that was ranked the max (i.e., “Pizza Slice”), you should update your program as follows:
menu_items = {
"Fries": 1.00,
"Apple": 0.25,
"Orange": 0.68,
"Mac n Cheese": 0.75,
"Pizza Slice": 0.80,
"Fresh Oven-baked Biscuits": 0.35
}
print("Item that appears last in order: " + max(menu_items))
print("Cost of the above item: " + str(menu_items[max(menu_items)]))
Note that in the second line, we are first applying max to find the key that is the highest, and then indexing into menu_items to find the cost and then converting it into a string so that we can concatenate it. The output is:
Item that appears last in order: Pizza Slice
Cost of the above item: 0.8
We can clean up the code above a little bit so that we do not compute the max twice in two successive lines:
menu_items = {
"Fries": 1.00,
"Apple": 0.25,
"Orange": 0.68,
"Mac n Cheese": 0.75,
"Pizza Slice": 0.80,
"Fresh Oven-baked Biscuits": 0.35
}
max_item = max(menu_items)
print("Item that appears last in order: " + max_item)
print("Cost of the above item: " + str(menu_items[max_item]))
The output is still:
Item that appears last in order: Pizza Slice
Cost of the above item: 0.8
Python max with lambda = identity function
The above code uses an implicit ordering mechanism to find the max(imum). And we can make this explicit in the following manner:
menu_items = {
"Fries": 1.00,
"Apple": 0.25,
"Orange": 0.68,
"Mac n Cheese": 0.75,
"Pizza Slice": 0.80,
"Fresh Oven-baked Biscuits": 0.35
}
max_item = max(menu_items, key = lambda x: x)
print("Item that appears last in order: " + max_item)
print("Cost of the above item: " + str(menu_items[max_item]))
Note that the max() function has been updated to have a second argument specifying the “key” to sort the collection by. The key is simply set to be a lambda function that is actually the identity function. The inputs to the lambda in this case are the names of the menu items and the lambda simply returns the name, and so the sorting order is by name. If you run this program, you will get the same output as before:
Item that appears last in order: Pizza Slice
Cost of the above item: 0.8
Python max with lambda to sort by price
We can change the lambda to instead sort by the price:
menu_items = {
"Fries": 1.00,
"Apple": 0.25,
"Orange": 0.68,
"Mac n Cheese": 0.75,
"Pizza Slice": 0.80,
"Fresh Oven-baked Biscuits": 0.35
}
max_item = max(menu_items, key = lambda x: menu_items[x])
print("Item that appears last in order: " + max_item)
print("Cost of the above item: " + str(menu_items[max_item]))
Note that the lambda’s key argument now returns the price as the item to sort by. The output is:
Item that appears last in order: Fries
Cost of the above item: 1.0
because Fries has the highest price, namely 1.00.
Python max with lambda to sort by length of key
Here is yet another way to sort. Let us sort by the length of the name of the item; in other words longer names appear later so the max() according to this criterion will be the item that has the longest name.
menu_items = {
"Fries": 1.00,
"Apple": 0.25,
"Orange": 0.68,
"Mac n Cheese": 0.75,
"Pizza Slice": 0.80,
"Fresh Oven-baked Biscuits": 0.35
}
max_item = max(menu_items, key=lambda x: len(x))
print("Item that appears last in order: " + max_item)
print("Cost of the above item: " + str(menu_items[max_item]))
The output is:
Item that appears last in order: Fresh Oven-baked Biscuits
Cost of the above item: 0.35
because “Fresh Oven-baked Biscuits” has the longest name.
Python max with lambda to sort by number of coins in price
Finally, here is a quirky way to sort. We will convert the price into coins (i.e., quarters, dimes, nickels, and pennies) and use the number of coins as the criterion to sort. For this purpose, we will write two additional functions, one to convert the price to coins and another to count the number of coins needed. Here is how that works:
def convert_price_to_coins(n):
quarter = 25; dime = 10; nickel = 5; penny = 1
coins = {}
if (n >= quarter):
coins["quarters"] = int(n / quarter)
n %= quarter
else:
coins["quarters"] = 0
if (n >= dime):
coins["dimes"] = int(n / dime)
n %= dime
else:
coins["dimes"] = 0
if (n >= nickel):
coins["nickels"] = int(n / nickel)
n %= nickel
else:
coins["nickels"] = 0
coins["pennies"] = n
return (coins)
def count_coins(price):
coin_list = convert_price_to_coins(price)
coins = 0
for x in coin_list.values():
coins = coins + x
return (coins)
menu_items = {
"Fries": 1.00,
"Apple": 0.25,
"Orange": 0.68,
"Mac n Cheese": 0.75,
"Pizza Slice": 0.80,
"Fresh Oven-baked Biscuits": 0.35
}
max_item = max(menu_items, key=lambda x: count_coins(menu_items[x]*100))
print("Item that appears last in order: " + max_item)
print("Cost of the above item: " + str(menu_items[max_item]))
In the convert_price_to_coins, we take the cost (given as input in cents) and progressively divide it by the largest denomination possible, from quarters to pennies, and accumulate the number of coins.
For instance, if we do:
print(convert_price_to_coins(70))
print(count_coins(70))
we will get:
{'quarters': 2, 'dimes': 2, 'nickels': 0, 'pennies': 0}
4
meaning we need 2 quarters and 2 dimes to get 70 cents. You do not need any nickels or pennies. The total coin count is 2+2=4 as printed by the count_coins() function.
In the lambda function, we use count_coins to setup the key (taking care to multiply by 100, because the prices of menu items in the dictionary are given in dollars whereas these functions expect input in cents).
If we run the above program, we get:
Item that appears last in order: Orange
Cost of the above item: 0.68
because purchasing an Orange requires the most number of coins.
So as you saw from the above examples, we can easily change the lambda in the max() function to define various meanings of what it means to be the maximum and thus create very expressive programs.
Can you think of additional ways to sort by creating your own lambda?
If you liked this blogpost, checkout our blogpost on whether you can create a multiline lambda function. Also learn about functors in Python.
For more Python content, checkout the math.ceil() and math.floor() functions! Also
learn about the math domain error in Python and how to fix it!
Interested in more things Python? Checkout our post on Python queues. Also see our blogpost on Python's enumerate() capability. Also if you like Python+math content, see our blogpost on Magic Squares. Finally, master the Python print function!
Want to learn Python with us? Sign up for 1:1 or small group classes.