Codectionary / Developer documentation / Python

Sorting with keys

Order records by a selected value while preserving the original data when needed.

How it works

sorted returns a new list from an iterable. list.sort changes an existing list and returns None. Both accept a key function that extracts the comparison value for each element.

Sorting is stable: records with equal keys retain their input order. A tuple key compares its first component, then later components when earlier components tie.

Choices and common mistakes

Choose whether callers should observe mutation before choosing sort or sorted. Assigning the result of list.sort loses the reference in that variable because its result is None.

Keys must be mutually orderable. Handle missing values or mixed types deliberately instead of assuming any collection can be sorted.

Try it yourself

Sort product dictionaries by category and then by price. Include two equal keys and check that their original relative order remains unchanged.

Syntax

sorted(records, key=lambda record: record["score"], reverse=True)

Examples

Preserve an input list

Sort words by length without changing their original order.

words = ["pear", "fig", "plum"]
ordered = sorted(words, key=len)
print(ordered)
print(words)
  1. len is passed as a callable rather than called immediately. Sorting uses each word length as its key.
  2. pear and plum tie at four characters and retain their original relative order. words itself is unchanged.
  3. Return a sorted view for presentation when other code still needs the original list order.
  4. Expected output: ['fig', 'pear', 'plum'] ['pear', 'fig', 'plum']

Rank records

Show the highest score first.

players = [{"name": "John", "score": 4}, {"name": "James", "score": 9}]
ranked = sorted(players, key=lambda player: player["score"], reverse=True)
print([player["name"] for player in ranked])
  1. The lambda reads a score from each dictionary. reverse=True orders larger scores before smaller scores.
  2. The result contains the original dictionary objects in a new list. It is not a deep copy of the records.
  3. Use key-based ranking for a report, and define a tie-breaker if your application needs one.
  4. Expected output: ['James', 'John']

Order by two fields

Use a tuple to express primary and secondary ordering.

records = [("B", 2), ("A", 3), ("A", 1)]
print(sorted(records, key=lambda row: (row[0], row[1])))
  1. The first key component groups A before B. Within A, the second component orders one before three.
  2. Both key components are ascending here. For mixed directions, use an appropriate key transformation or multiple stable sorts.
  3. A category-and-price listing is a common use for multi-field ordering.
  4. Expected output: [('A', 1), ('A', 3), ('B', 2)]

Best practices

  • Choose whether callers should observe mutation before choosing sort or sorted. Assigning the result of list.sort loses the reference in that variable because its result is None.
  • Keys must be mutually orderable. Handle missing values or mixed types deliberately instead of assuming any collection can be sorted.

Runtime & versions

Python interpreter. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Python language reference

Specifications & further reading