Python • Collections and Strings

Sorting with Key Functions — Sort with sorted() and list.sort(); use key functions (intro)

Master Python's powerful sorting tools and learn how key functions let you sort data any way you want.

Code braces with terminal and markup symbols representing Python programming.
Inside this lesson 10 sections 5 questions 7 figures

SECTION 1

Historical Context & Motivation

Sorting is one of the most fundamental operations in computer science. Every time you organize a playlist alphabetically, rank scores from highest to lowest, or filter search results by relevance, a sorting algorithm is doing the heavy lifting behind the scenes. Early programming languages forced developers to write their own sorting code from scratch, which was error-prone and time-consuming.

Python's designers recognized that sorting was so common that it deserved built-in, optimized tools. Over time, Python evolved its sorting capabilities from basic comparison-based methods to the elegant key function approach we use today. This lets you tell Python how to compare items, rather than writing the comparison logic yourself.

1991 • Python 1.0 Released

Guido van Rossum releases Python with basic list sorting via list.sort(), using a simple comparison-based approach.

2002 • Timsort Introduced

Tim Peters creates Timsort, a hybrid sorting algorithm that becomes Python's default. It is optimized for real-world data and remains the engine behind Python sorting today.

2004 • sorted() Built-in Added

Python 2.4 introduces the sorted() built-in function, which returns a new sorted list from any iterable without modifying the original.

2008 • Python 3.0 — Key Functions Only

Python 3 removes the old cmp parameter and standardizes on key functions as the preferred way to customize sorting behavior.

The central question this lesson addresses is straightforward: how do you sort data in Python when the default alphabetical or numerical order isn't what you need? For example, how would you sort a list of names by their length instead of alphabetically? That's where key functions come in.

SECTION 2

Core Principles & Definitions

Before diving into code, let's establish the foundational ideas behind Python's sorting tools. Understanding these principles will make every sorting task feel intuitive.

1

sorted() — Returns a New List

The sorted() function takes any iterable (list, tuple, string, etc.) and returns a brand-new sorted list. The original data remains unchanged.
2

list.sort() — Sorts In Place

The .sort() method modifies the original list directly and returns None. This is called in-place sorting and saves memory for large lists.
3

The key Parameter

Both sorted() and .sort() accept a key parameter — a function that transforms each item before comparison. Python sorts by the transformed values but keeps the original items.
4

The reverse Parameter

Setting reverse=True sorts in descending order (largest to smallest, Z to A). It works alongside key to give you full control over sort direction.
5

Stable Sorting

Python's sort is stable, meaning items that compare as equal keep their original relative order. This is important when sorting by one key after another.
✦

KEY TAKEAWAY

Think of a key function like a label maker. Imagine you have a box of toys and you want to line them up by weight. You don't rearrange the toys differently — you just stick a weight label on each one, sort by the labels, then remove them. The key function creates those temporary labels that Python uses for comparisons.

SECTION 3

Visual Explanation — How Key Functions Work

The diagram below shows the step-by-step process that Python follows when you call sorted(words, key=len). Notice how the key function creates temporary "sort keys" that determine the final order, but the output contains the original items — not the key values.

How sorted(words, key=len) Workswords = ["banana", "pie", "kiwi", "strawberry"]STEP 1: Apply key=len to each item"banana"6"pie"3"kiwi"4"strawberry"10STEP 2: Sort by key values (3, 4, 6, 10)"pie"key=3"kiwi"key=4"banana"key=6"strawberry"key=10STEP 3: Return original items in new order["pie", "kiwi", "banana", "strawberry"]✓ Sorted by string length (shortest → longest)
The key function len transforms each string into its length. Python sorts by these key values (3, 4, 6, 10) but returns the original strings in the new order.

The critical insight here is that the key function acts as a transformation layer. Python never actually rearranges the key values themselves — it uses them temporarily to decide the order, then discards them. Your final output always contains the original, untransformed items. This pattern is sometimes called decorate-sort-undecorate because you "decorate" items with sort keys, sort by those keys, then "undecorate" to get the originals back.

SECTION 4

How It Works — Syntax & Mechanics

Let's break down the exact syntax for both sorting approaches and see how the key parameter fits in.

SORTED() SYNTAX

sorted(iterable,key=None,reverse=False)sorted(iterable, key=None, reverse=False)

iterable — any collection (list, tuple, string, etc.). key — a function applied to each item before comparison (default: None, meaning compare items directly). reverse — if True, sort in descending order. Returns a new list.

LIST.SORT() SYNTAX

list.sort(key=None,reverse=False)list.sort(key=None, reverse=False)

Same key and reverse parameters, but this is a method on list objects. It modifies the list in place and returns None.

What Can Be a Key Function?

The key parameter accepts any callable that takes one argument and returns a value. This can be a built-in function like len or str.lower, a function you define with def, or a lambda expression (a small anonymous function). For now, we'll focus on built-in functions and simple lambdas.

⚠

Common Mistake

Don't call the function when passing it as a key! Write key=len (correct — passes the function itself) not key=len() (wrong — calls len with no arguments and causes an error). You are handing Python the function so it can call it on each item.

Here's a quick example using a lambda. A lambda is a tiny one-line function. The expression lambda x: x[1] means "given an item x, return its element at index 1." So sorted(pairs, key=lambda x: x[1]) sorts a list of tuples by their second element.

SECTION 5

Common Key Functions — A Classification

Key functions come in many forms. The table below shows the most common patterns you'll encounter, along with what each one does and when to use it.

Key FunctionWhat It DoesExample Use Case
key=lenSorts by the length of each itemSort words shortest to longest
key=str.lowerSorts strings case-insensitivelySort names ignoring capitalization
key=absSorts by absolute valueSort numbers by magnitude
key=lambda x: x[1]Sorts by the second element of each itemSort (name, score) tuples by score
key=lambda s: s[-1]Sorts by the last characterSort words by their ending letter

Common key functions used with sorted() and list.sort()

sorted() vs list.sort() — Side by Sidesorted()list.sort()nums = [4, 1, 7, 2]nums = [4, 1, 7, 2]result = sorted(nums)nums.sort()After sorting:After sorting:result→ [1, 2, 4, 7]nums→ [4, 1, 7, 2]✓ Original unchangednums→ [1, 2, 4, 7]returns None⚠ Original is modifiedWith key function:With key function:sorted(words, key=len)→ new list, sorted by lengthwords.sort(key=len)→ words modified in placeBest for:• Any iterable input• When you need the original intactBest for:• Lists only• When you want to save memory
Side-by-side comparison of sorted() (creates a new list) and list.sort() (modifies the original). Both accept the same key and reverse parameters.

As you can see, choosing between sorted() and list.sort() depends on whether you need to preserve the original list. If you're processing data and want to keep a copy of the unsorted version, sorted() is the safer choice. If you're done with the old order and want to save memory, list.sort() is more efficient.

SECTION 6

Worked Example — Sorting Student Records

Let's walk through a realistic scenario. You have a list of student records stored as tuples, and you need to sort them by grade (highest first).

Sort Students by Grade (Descending)

  1. 1

    Step 1 — Define the Data

    We have a list of tuples, where each tuple contains a student's name and their grade: students = [("Alice", 88), ("Bob", 95), ("Charlie", 72), ("Diana", 91)]
  2. 2

    Step 2 — Identify the Key

    We want to sort by the grade, which is the second element of each tuple (index 1). Our key function is lambda student: student[1]. This takes each tuple and returns just the numeric grade.
  3. 3

    Step 3 — Choose sorted() or .sort()

    We'll use sorted() so the original list stays intact. Since we want highest grades first, we also set reverse=True.
  4. 4

    Step 4 — Write the Code

    The complete expression is: ranked = sorted(students, key=lambda student: student[1], reverse=True)
  5. 5

    Step 5 — Verify the Output

    Python applies the lambda to each tuple: 88, 95, 72, 91. It sorts these values in descending order: 95, 91, 88, 72. Then it returns the original tuples in that order.
    [("Bob", 95), ("Diana", 91), ("Alice", 88), ("Charlie", 72)]
💡

Try It Yourself

Open a Python interpreter and paste this code. Then try changing the key to lambda student: student[0] to sort by name instead. Remove reverse=True to see the default ascending order.

SECTION 7

sorted() vs list.sort() — Strengths & Limitations

Featuresorted()list.sort()
Return valueNew sorted listNone (modifies in place)
Input typesAny iterable (list, tuple, string, dict, set, generator)Lists only
Original dataPreserved — untouchedOverwritten — old order lost
Memory usageUses extra memory for the new listMore memory-efficient (no copy)
ChainingCan chain with other operations since it returns a listCannot chain — returns None
key & reverse✓ Supported✓ Supported

Feature comparison between sorted() and list.sort()

🔑

WHEN TO USE WHICH

Think of it like editing a photo. sorted() is like applying a filter and saving a copy — the original is still on your camera roll. list.sort() is like editing the original file directly — faster, but the old version is gone. When in doubt, use sorted() because it's safer and more flexible.

SECTION 8

Connection to Advanced Sorting Techniques

The key function concept you've learned here is the foundation for more advanced sorting patterns you'll encounter as you progress in Python. Understanding how keys work now will make these techniques easy to pick up later.

What You Know NowWhat's Coming Next
Simple key functions like len and str.lowerMulti-level sorting with operator.itemgetter() and operator.attrgetter()
Lambda functions for simple transformationsCustom classes with __lt__ and other comparison methods
Sorting by one criterionSorting by multiple criteria using tuples as keys, e.g., key=lambda x: (x[1], x[0])
Using reverse=True for descending orderMixing ascending and descending order in multi-key sorts using negative values

From introductory to advanced sorting concepts

One particularly powerful technique is multi-key sorting. Because Python's sort is stable, you can sort by one key, then sort again by another key, and items that tie on the second key will remain in the order established by the first sort. Alternatively, you can return a tuple from your key function to sort by multiple criteria at once. These techniques build directly on everything you've learned in this lesson.

ℹ

Looking Ahead

Python's functools.cmp_to_key() function can convert an old-style comparison function into a key function. You won't need this often, but it's good to know it exists for edge cases where a key function alone isn't enough.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

What is the difference between sorted(my_list) and my_list.sort()? If you wrote x = my_list.sort(), what value would x hold, and why?
Show answer
sorted(my_list) creates and returns a brand-new sorted list, leaving my_list unchanged. In contrast, my_list.sort() sorts the list in place and returns None. So if you wrote x = my_list.sort(), x would be None. This is a common beginner mistake — the sort happens on my_list directly, so the method doesn't need to return anything.

Question 2: BASIC CALCULATION

Given words = ["elephant", "cat", "bear", "dolphin"], what is the output of sorted(words, key=len)?
Show answer
First, apply len to each word: "elephant" → 8, "cat" → 3, "bear" → 4, "dolphin" → 7. Sorting these key values in ascending order gives 3, 4, 7, 8. The result is ["cat", "bear", "dolphin", "elephant"]. Notice that the original strings are returned, not the numbers. The key function only determines the ordering.

Question 3: INTERMEDIATE

You have scores = [("Math", 92), ("English", 85), ("Science", 97), ("History", 85)]. Write an expression using sorted() that sorts these tuples by score in descending order. If two subjects have the same score, should their order change? Explain why or why not.
Show answer
The expression is sorted(scores, key=lambda x: x[1], reverse=True). This produces [("Science", 97), ("Math", 92), ("English", 85), ("History", 85)]. English and History both have a score of 85, and they appear in the same relative order as the original list (English before History). This happens because Python's sort is stable — items with equal keys maintain their original order. Stability is guaranteed by Python's Timsort algorithm.

Question 4: APPLIED

You are building a simple contact list app. You have contacts = ["Zara Smith", "alice Johnson", "Bob MARTINEZ", "charlie Lee"]. Users expect contacts sorted alphabetically regardless of capitalization. Write the code to produce a case-insensitive alphabetical sort, and explain which key function you used and why.
Show answer
Use sorted(contacts, key=str.lower). The key function str.lower converts each string to lowercase before comparison. Without it, uppercase letters sort before lowercase letters in Python (because of ASCII/Unicode ordering), so "Bob" would appear before "alice". The result is ["alice Johnson", "Bob MARTINEZ", "charlie Lee", "Zara Smith"]. The original strings are preserved in the output — only the comparison uses the lowered versions.

Question 5: CRITICAL THINKING

Consider the list data = ["3", "15", "7", "100", "22"]. What does sorted(data) return, and why might this surprise you? Then write a version using a key function that sorts these strings by their actual numeric value. Explain the difference.
Show answer
sorted(data) returns ["100", "15", "22", "3", "7"] because Python compares strings character by character (lexicographic order). The string "100" starts with "1", which comes before "3" in character order. To sort by numeric value, use sorted(data, key=int), which converts each string to an integer for comparison. This gives ["3", "7", "15", "22", "100"]. The output still contains the original strings, not integers — the int conversion is only used for ordering. This is a classic example of why key functions are so important in real programs.

SUMMARY

Lesson Summary

Summary

Python provides two primary tools for sorting: sorted(), which returns a new sorted list from any iterable, and list.sort(), which sorts a list in place and returns None. Both methods accept a key parameter — a function that transforms each item into a sort key before comparison — and a reverse parameter to switch between ascending and descending order.

Common key functions include len for sorting by length, str.lower for case-insensitive sorting, int for numeric sorting of strings, and lambda expressions for custom transformations like accessing tuple elements. Python's sort is stable, meaning equal elements retain their original order. The key function creates temporary comparison values but the output always contains the original, untransformed items.

Varsity Tutors • Python • Sorting with Key Functions