22  Sorting Lists

A sorting operation will arrange items in a specific order.

In Python, we can use the sorted function to sort a list. To use the sorted function, we pass in as the first parameter the list we want to sort.

In the case of simple lists, this is sufficient:

symbols = ["MSFT", "AAPL", "GOOGL", "AMZN", "NFLX"]
print(type(symbols))
print(symbols)
<class 'list'>
['MSFT', 'AAPL', 'GOOGL', 'AMZN', 'NFLX']
sorted(symbols)
['AAPL', 'AMZN', 'GOOGL', 'MSFT', 'NFLX']

Notice, this is not a mutating operation, so if we want to use the results, we’ll need to store the sorted list in a variable for later:

print(symbols)

print(sorted(symbols))

print(symbols) # ORIGINAL, UNSORTED LIST
['MSFT', 'AAPL', 'GOOGL', 'AMZN', 'NFLX']
['AAPL', 'AMZN', 'GOOGL', 'MSFT', 'NFLX']
['MSFT', 'AAPL', 'GOOGL', 'AMZN', 'NFLX']
print(symbols)

sorted_symbols = sorted(symbols) # STORING THE RESULT FOR LATER

print(sorted_symbols) # NOW ITS SORTED
['MSFT', 'AAPL', 'GOOGL', 'AMZN', 'NFLX']
['AAPL', 'AMZN', 'GOOGL', 'MSFT', 'NFLX']

There are some optional parameters we can use, for example, after consulting the function documentation, we see the reverse parameter takes a boolean value to determine which order the list should be sorted in (ascending or descending):

sorted(symbols, reverse=False) # ASCENDING ORDER, SAME AS DEFAULT
['AAPL', 'AMZN', 'GOOGL', 'MSFT', 'NFLX']
sorted(symbols, reverse=True) # DESCENDING ORDER
['NFLX', 'MSFT', 'GOOGL', 'AMZN', 'AAPL']

22.1 Sorting Complex Lists

We see that if we have a simple list, such as a list of numbers or list of strings, the sorted function will know how to sort the items. It understands numeric order in which 2 is greater than 1, and it understands alphabetical order in which “b” is greater than “a”.

print(1 < 2)
print("a" < "b")
True
True

But it is not possible to compare dictionaries using greater than or less than operators:

# print({} < {}) # INVALID
#> TypeError: '<' not supported between instances of 'dict' and 'dict'

So if we have a complex list, such as a list of dictionaries, we need to specify on the basis of which key we should sort on.

teams = [
    {"city": "New York", "name": "Yankees"},
    {"city": "New York", "name": "Mets"},
    {"city": "Boston", "name": "Red Sox"},
    {"city": "New Haven", "name": "Ravens"}
]
#sorted(teams) # INVALID
#> TypeError: '<' not supported between instances of 'dict' and 'dict'

The key parameter is used for this purpose. In practice, when specifying what key to sort on, we can use a lambda statement, a custom function, or the itemgetter function from the operator module. All of the following approaches are equivalent:

# itemgetter function approach:

from operator import itemgetter

sorted(teams, key=itemgetter("name"))
[{'city': 'New York', 'name': 'Mets'},
 {'city': 'New Haven', 'name': 'Ravens'},
 {'city': 'Boston', 'name': 'Red Sox'},
 {'city': 'New York', 'name': 'Yankees'}]
# custom function approach:

def sort_by_name(team):
    return team["name"]

sorted(teams, key=sort_by_name)
[{'city': 'New York', 'name': 'Mets'},
 {'city': 'New Haven', 'name': 'Ravens'},
 {'city': 'Boston', 'name': 'Red Sox'},
 {'city': 'New York', 'name': 'Yankees'}]
# lambda syntax approach:

sorted(teams, key= lambda team: team["name"])
[{'city': 'New York', 'name': 'Mets'},
 {'city': 'New Haven', 'name': 'Ravens'},
 {'city': 'Boston', 'name': 'Red Sox'},
 {'city': 'New York', 'name': 'Yankees'}]