diff --git a/README.md b/README.md index 04d172b..7765fb9 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). -_1775 TILs and counting..._ +_1776 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 - [Keep A Tally With collections.Counter](python/keep-a-tally-with-collections-counter.md) - [Load A File Into The Python REPL](python/load-a-file-into-the-python-repl.md) - [Look Inside Pytest tmp_path](python/look-inside-pytest-tmp-path.md) +- [Make Dataclass Sortable By Specific Field](python/make-dataclass-sortable-by-specific-field.md) - [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) diff --git a/python/make-dataclass-sortable-by-specific-field.md b/python/make-dataclass-sortable-by-specific-field.md new file mode 100644 index 0000000..23892bc --- /dev/null +++ b/python/make-dataclass-sortable-by-specific-field.md @@ -0,0 +1,45 @@ +# Make Dataclass Sortable By Specific Field + +One way to sort a list of some `dataclass` is to define the `key` parameter when +calling `sort` or `sorted` like I discussed in [Sort a List of Dataclass +Instances](sort-a-list-of-dataclass-instances.md): + +```python +for date in sessions_grouped_by_day.keys(): + sessions_grouped_by_day[date].sort( + key=lambda session: session.start_time.time() + ) +``` + +But then that lambda for `key` needs to be defined everywhere you sort. + +If the dataclass has a single, specific field that acts as a natural proxy for +sort order, then you can define that in the `dataclass` implementation with the +`__lt__` method. + +As long as a class defines the _less than_ dunder method, it will be sortable. + +Here is what that looks like for this `Session` dataclass: + +```python +from dataclasses import dataclass +from datetime import datetime, timezone + +@dataclass +class Session: + start_time: datetime + project_name: str + end_time: datetime | None = None + + def __lt__(self, other): + if not isinstance(other, Session): + return NotImplemented + return self.start_time < other.start_time + + # more methods below ... +``` + +This implementation of `__lt__` tells the sorting methods that _this_ (`self`) +instance of `Session` can be compared to some `other` instance of `Session` by +comparing their `start_time` values to see which is less than. The guard at the +beginning makes sure only instances of `Session` are being compared.