fluttersmith/py-snippetsGitHub ↗

Sort a list by a matching list of positions

Order items by the number at the same position in a second list.

Lists#sortingO(n log n) time✓ 4 examples pass on 3.11–3.14

You have names in one list and their ranks in another. Pair them, sort by rank, keep the names.

sort_by_indexes.py✓ ruff · mypy --strict
from collections.abc import Iterable
from operator import itemgetter
from typing import TypeVar

T = TypeVar("T")


def sort_by_indexes(
    items: Iterable[T], indexes: Iterable[float], *, reverse: bool = False
) -> list[T]:
    """Sort ``items`` by the matching number in ``indexes``."""
    pairs = zip(indexes, items, strict=True)
    return [item for _, item in sorted(pairs, key=itemgetter(0), reverse=reverse)]
  1. strict=True: a missing index is an error, not a silent drop
  2. sort on the index only, so items never get compared
examples✓ 4 doctests · 3.11–3.14
passed on Python 3.11 to 3.14: >>> food = ["eggs", "bread", "oranges", "jam", "apples", "milk"]passed on Python 3.11 to 3.14: >>> sort_by_indexes(food, [3, 2, 6, 4, 1, 5])['apples', 'bread', 'eggs', 'jam', 'milk', 'oranges']passed on Python 3.11 to 3.14: >>> sort_by_indexes(food, [3, 2, 6, 4, 1, 5], reverse=True)['oranges', 'milk', 'jam', 'eggs', 'bread', 'apples']passed on Python 3.11 to 3.14: >>> sort_by_indexes("abc", [1, 2])Traceback (most recent call last):...ValueError: zip() argument 2 is longer than argument 1
Edit the function or the examples and run the doctests here, on Python 3.14. Python loads only when you click (about 7 MB, cached after the first time).

How it works

  • zip(..., strict=True) pairs each index with its item, and raises if the lengths differ.
  • The sort key is the index alone. Sorting the raw pairs would compare items whenever two indexes tie, which fails for dicts.
  • sorted is stable: equal indexes keep their original order.

Complexity: O(n log n) time, O(n) space

Importfrom pysnippets.lists.sort_by_indexes import sort_by_indexesNo dependencies: copy sort_by_indexes.py into your project, or clone the repo.

Adapted from sort-by-indexes in 30-seconds-of-python by the 30 seconds of code contributors, CC BY 4.0. Changed: Sorts on the index only, rejects mismatched lengths; typed. Suggest an edit.