Vocabulary for this course

The terms the chapters assume, in plain words. You can open this from any chapter.

argument
A value you put inside the parentheses when you call a function, which the function then receives.
block
A group of lines that belong together under one opening line, such as the body of an if or a loop.
branch
A path a program can take when a condition sends it one way or another.
call site
The place in the code where a function is called, as opposed to where it is defined.
class
A template that bundles data with the code that works on it; each copy has its own values.
dictionary
A collection of key and value pairs, where a key is used to look up its value.
exception
An error that stops the normal flow of a program unless some code catches it.
function
A named piece of code that does one job and can be called whenever you need it.
function object
A function treated as a value, so it can be stored in a variable, passed to another function, or returned.
indentation
The spaces at the start of a line that show which block it belongs to.
integer
A whole number with no decimal point, such as 3, 0 or -12.
list
An ordered collection of values that you can grow, shrink and reach into by position.
parameter
A name in a function definition that stands for the value the caller will supply.
return value
The result a function hands back to the code that called it.
scope
The part of a program where a name can be used; a name made inside a function is not visible outside it.
traceback
The report Python prints when a program fails, listing the calls that led to the error.
variable
A name that refers to a value, so you can use that value again later or change it.

Python from the ground up

Sorting and comprehensions

Putting a list in order, and building a new one from an old one — the two lines that replace a lot of loops.

Part 12 of 15

Intermediate15 min readBack to Courses

Sorted makes a new list

sorted(words) hands back a new list in order and leaves the original alone; the list method words.sort() reorders the list itself. Reaching for sorted first is the habit that avoids the bug where a function quietly rearranges the caller’s data.

key= names what to sort by. sorted(words, key=len) orders by length, shortest first; sorted(recipes, key=minutes) orders by whatever a small function returns for each item — one function, and the ordering can be anything you can calculate.

Two orders, same list

words = ["banana", "fig", "cherry", "apple"]

print(sorted(words))
print(sorted(words, key=len))

recipes = [{"name": "Soup", "minutes": 40}, {"name": "Toast", "minutes": 5}]
print(sorted(recipes, key=lambda recipe: recipe["minutes"]))

A loop that builds a list, in one line

A comprehension is a loop that collects its results. [word.upper() for word in words] walks the list and builds a new one, in the same order — the same work as a for loop with an append, written where the list is used instead of four lines away.

Add a condition at the end and it filters while it builds: [word for word in words if len(word) > 4] keeps only the long ones. The result is always a new list; the old one is untouched.

Dictionaries are built the same way

Curly braces with a key and a value do the same for dictionaries: {word: len(word) for word in words} is a lookup table from each word to its length. One line, and the shape of the data explains itself.

Comprehensions stop being readable when they try to do three things at once. When one needs a comment to explain itself, it wants to be a loop again.

Shortest first, then first letters

Sort the words by length, shortest first, and print the first letter of each word as one joined string using a list comprehension.

Output
Click "Run" to execute your code

Text sorts by character, numbers by value

sorted compares items with <, and what that means depends on the type. Numbers compare by size, so 9 comes before 10. Text compares character by character, so "10" comes before "9" because the character 1 precedes 9. A list of numbers stored as text therefore sorts into an order that looks wrong and is technically correct.

The fix is to sort by a key that returns a number: key=int for text that holds whole numbers, or key=float for prices. The same idea applies to dates written as text in a format that does not sort — convert first, then order.

A comprehension is an expression, not a loop

The result of a comprehension is a value, so it can be printed, returned, or passed straight into another call. It cannot contain a print statement in the middle, and it should not try: a comprehension that exists for its side effects is a loop wearing the wrong shape.

When the body needs more than one step, write the loop. The four-line version is not a failure; it is the version a reader can put a breakpoint in. Use the short form when the transformation fits in one expression, and stop when it does not.

key=len passes the function itself, without brackets. With brackets you would be calling it and sorting by the result for every item at once, which is almost never what you meant.

The key is calculated, then compared

sorted(items, key=...) runs the key function once for each item and sorts by the results. The original values are not changed, and the key does not have to return text — any values that can be compared with each other work.

Sorting is stable: when two keys tie, the items keep their original order. That is why sorting by one field and then by another can build a multi-level order, and why reverse=True flips the comparison without shuffling ties.

What a comprehension does, in order

A comprehension reads in two parts: the expression before for says what each new item is, and the if at the end says which originals qualify. The condition is checked before the expression runs.

That order matters when the expression is expensive or could fail: a filtered comprehension never evaluates it for a rejected item. It is also why the result is a new list rather than a changed one.

Three sorting mistakes: key=len() calls the function immediately instead of passing it, which is a TypeError; words.sort() returns None, so sorted_words = words.sort() throws the list away; and sorting a mix of text and numbers raises TypeError because Python will not guess an order between them.

Try these next

  • Sort a list of names by length, then alphabetically, and compare the orders.
  • Sort numbers with reverse=True, then compare that with sorted(numbers)[::-1]; they should match.
  • Write key=len() once, read the error, and remove the brackets.

Rank the runners

Sort the runners by their time, fastest first, and print each one with a place number. Then add a fourth runner and check the places still start at 1.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

What is the difference between sorted(words) and words.sort()?