From b873f86f5b4ee3e9b47d9a921b6f2934276c76bb Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Wed, 1 Apr 2026 20:38:20 -0500 Subject: [PATCH] Add Sort A List Of Dataclass Instances as a Python TIL --- README.md | 3 +- python/sort-a-list-of-dataclass-instances.md | 52 ++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 python/sort-a-list-of-dataclass-instances.md diff --git a/README.md b/README.md index 7df2ff4..92ec913 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/). For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter). -_1771 TILs and counting..._ +_1772 TILs and counting..._ See some of the other learning resources I work on: @@ -1063,6 +1063,7 @@ If you've learned something here, support my efforts writing daily TILs by - [Override The Boolean Context Of A Class](python/override-the-boolean-context-of-a-class.md) - [Parse Relative Time To datetime Object](python/parse-relative-time-to-datetime-object.md) - [Skip Specific Pytest Test Cases](python/skip-specific-pytest-test-cases.md) +- [Sort A List Of Dataclass Instances](python/sort-a-list-of-dataclass-instances.md) - [Start The Debugger When A Test Errors](python/start-the-debugger-when-a-test-errors.md) - [Store And Access Immutable Data In A Tuple](python/store-and-access-immutable-data-in-a-tuple.md) - [Test A Function With Pytest](python/test-a-function-with-pytest.md) diff --git a/python/sort-a-list-of-dataclass-instances.md b/python/sort-a-list-of-dataclass-instances.md new file mode 100644 index 0000000..69380ce --- /dev/null +++ b/python/sort-a-list-of-dataclass-instances.md @@ -0,0 +1,52 @@ +# Sort A List Of Dataclass Instances + +Sorting lists of scalar values (integers, strings, floats, even booleans) in +Python is simple because the natural ordering of the list elements will be used. +We can call `sorted` on the list and it _just works_. + +```python +>>> items = ["orange", "apple", "banana", "mango"] +>>> sorted(items) +['apple', 'banana', 'mango', 'orange'] +``` + +However, if we have a list of non-scalar values, it is a little more complex. We +have to give `sorted` some help with knowing how to sort things that don't have +a natural ordering. + +Let's take this `dataclass` that represents a time-based `Session` as an +example. + +```python +from dataclasses import dataclass +from datetime import datetime, timezone + +@dataclass +class Session: + start_time: datetime + project_name: str + end_time: datetime | None = None + + # plus several methods ... +``` + +If I have a list of `Session` instances that I want to sort, I have to give +`sorted` a `key` to sort on. In the case of these `Session` instances, we'll +pass a `lambda` that can be evaluated to determine the sort value (which needs +to be sortable). `datetime` instances are sortable and I want to sort these +sessions based on their `start_time` values. + +Here is a snippet from my `py_vmt` CLI where I make sure that each list of +sessions in this day-by-day `dict` is sorted based on the `start_time`: + +```python +for date in sessions_grouped_by_day.keys(): + sessions_grouped_by_day[date].sort( + key=lambda session: session.start_time.time() + ) +``` + +`sort` (and `sorted`) translates each item in the list to the values produced +by the lambda and then sorts them by those values. + +[source](https://docs.python.org/3/howto/sorting.html)