1 of 16

Sorting and Itemgetter

Winter 2025

1

Adrian Salguero

2 of 16

Announcements

  • Homework 4, Part 2 due tonight at 11:59pm
    • Any fixes made for Homework 4, Part 1 can be submitted as part of Homework 4, Part 2 without the use of a resubmission
  • Coding Practice 6 due Wednesday, February 26 at 11:59pm
  • I will be travelling most of next week for a research conference
    • John (your TA) will run lecture on Wednesday (Feb. 26) and Friday (Feb. 28)
    • My office hours/appointments will be cancelled this week

2

3 of 16

sorted vs. sort

  • sorted(itr) - a function that takes an iterable as a parameter (e.g. sequence types: list, string, tuple) and returns a sorted version of that parameter
  • lst.sort() - a method that sorts the list that it is called on in-place (returns None). .sort() can only be called on lists

3

4 of 16

sorted vs. sort example

hamlet = "to be or not to be that is the question whether tis nobler in the mind to suffer".split()

print("hamlet:", hamlet)

print("sorted(hamlet):", sorted(hamlet))

print("hamlet:", hamlet)

print("hamlet.sort():", hamlet.sort())

print("hamlet:", hamlet)

4

Modifies the list in place, returns None

Returns a new sorted list (does not modify the original list)

5 of 16

Customizing the sort order

Suppose we have a list of names and our goal is to sort them by last name

names = ["Isaac Newton", "Albert Einstein", "Niels Bohr", "Marie Curie", "Charles Darwin", "Louis Pasteur", "Galileo Galilei", "Margaret Mead"]

The following does not work, why?

When sorting, how should we be comparing these names?

5

print("sorted(names):", sorted(names))

6 of 16

Sort key

  • A sort key is a function that can be called on each list element to extract/create a value that will be used to make comparisons

fruits = ["watermelon", "fig", "apple"]

print(sorted(fruits)) # alphabetical sort

print(sorted(fruits, key = len)) # sort using length (shortest to longest)

# What if we added a capital version of Watermelon?

# What if we wanted the longest to shortest sorting?

6

7 of 16

Using sort key to sort by last name

  • What function allows us to get the last name of a string?
    • We need to write one! A very simple one.*

*This function only works on two-word names. Does not consider all possible types of names

def last_name(name):

return name.split(" ")[1]

print('last_name("Isaac Newton"):', last_name("Isaac Newton"))

7

8 of 16

Using sort key to sort by last name

def last_name(name):

return name.split(" ")[1]

names = ["Isaac Newton", "Ada Lovelace", "Fig Newton", "Grace Hopper"]

print(sorted(names, key=last_name))

print(sorted(names, key=len))

def last_name_len(name):

return len(last_name(name))

print(sorted(names, key=last_name_len))

8

If there is a tie in last names, preserves original order of values.

9 of 16

itemgetter is a function

that returns a function

Useful for creating a function that will return particular elements from a sequence (e.g., list, string, tuple)

import operator

operator.itemgetter(2)([7, 3, 8]) # 8

operator.itemgetter(0)([7, 3, 8]) # 7

operator.itemgetter(1)([7, 3, 8]) # 3

operator.itemgetter(0, 1)([7, 3, 8]) # (7, 3)

operator.itemgetter(3)([7, 3, 8]) # IndexError: list index out of range

Read the Documentation: https://docs.python.org/3/library/operator.html

9

Returns a function

Call function passing in this list as an argument

A tuple

10 of 16

itemgetter Exercise

import operator

lst1 = [2, 7, 3, 9, 4]

print(operator.itemgetter(1)(lst1))

print(operator.itemgetter(1, 2)(lst1))

print(operator.itemgetter(2, 3)(lst1))

tup2 = operator.itemgetter(3, 2, 1, 0)(lst1)

print(tup2)

print(operator.itemgetter(0)(tup2))

get_second = operator.itemgetter(1)

print(get_second(tup2))

print(operator.itemgetter(2)("howdy"))

print(operator.itemgetter(2, 0, 1)("howdy"))

10

11 of 16

Two ways to import itemgetter

import operator

student_score = ('Robert', 8)

operator.itemgetter(0)(student_score) ⇒ “Robert”

operator.itemgetter(1)(student_score) ⇒ 8

Or

from operator import itemgetter

student_score = ('Robert', 8)

itemgetter(0)(student_score) ⇒ “Robert”

itemgetter(1)(student_score) ⇒ 8

11

A tuple

Another way to import, allows you to call itemgetter directly.

12 of 16

Using itemgetter

from operator import itemgetter

student_score = ('Robert', 8)

itemgetter(0)(student_score) ⇒ “Robert”

itemgetter(1)(student_score) ⇒ 8

student_scores = [('Robert', 8), ('Alice', 9), ('Tina', 7)]

#Sort the list by name:

sorted(student_scores, key=itemgetter(0))

#Sort the list by score

sorted(student_scores, key=itemgetter(1))

12

Another way to import, allows you to call itemgetter directly.

What would sorted(student_scores) return?

13 of 16

Sorting based on two criteria

Goal: sort based on score, if there is a tie within score, sort by name

Two approaches:

  1. Sort twice (most important sort last)
  2. Use itemgetter with two arguments

student_scores = [('Robert', 8), ('Alice', 9),

('Tina', 10), ('James', 8)]

#Approach #1:

sorted_by_name = sorted(student_scores, key=itemgetter(0))

sorted_by_score = sorted(sorted_by_name, key=itemgetter(1))

#Approach #2:

sorted(student_scores, key=itemgetter(1,0))

13

14 of 16

Sort on most important criteria LAST

  • Sorted by score (ascending), when there is a tie on score, sort using name

from operator import itemgetter

student_scores = [('Robert', 8), ('Alice', 9), ('Tina', 10), ('James', 8)]

sorted_by_name = sorted(student_scores, key=itemgetter(0))

>>> sorted_by_name

[('Alice', 9), ('James', 8), ('Robert', 8), ('Tina', 10)]

sorted_by_score = sorted(sorted_by_name, key=itemgetter(1))

>>> sorted_by_score

[('James', 8), ('Robert', 8), ('Alice', 9), ('Tina', 10)]

14

15 of 16

More sorting based on two criteria

If you want to sort different criteria in different directions, you must use multiple calls to sort or sorted

student_scores = [('Robert', 8), ('Alice', 9), ('Tina', 10), ('James', 8)]

Goal: sort score from highest to lowest; if there is a tie within score, sort by name alphabetically (= lowest to highest)

sorted_by_name = sorted(student_scores, key=itemgetter(0))

sorted_by_hi_score = sorted(sorted_by_name, key=itemgetter(1), reverse=True)

15

Remember: Sort on most important criteria LAST

16 of 16

Sorting Exercise

from operator import itemgetter

student_scores = [('Ann', 7), ('Raul', 6), ('Ted', 4), ('Lisa', 6)]

print(sorted(student_scores, key=itemgetter(1)))

lst_a = sorted(student_scores, key=itemgetter(0))

print(lst_a)

lst_b = sorted(lst_a, key=itemgetter(1))

print(lst_b)

lst_c = sorted(lst_a, key=itemgetter(1), reverse=True)

print(lst_c)

16