diff --git a/README.md b/README.md index 2d8097b..6b6b015 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). -_1779 TILs and counting..._ +_1780 TILs and counting..._ See some of the other learning resources I work on: @@ -1070,6 +1070,7 @@ If you've learned something here, support my efforts writing daily TILs by - [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) +- [Sort Normalized Version Of Data](python/sort-normalized-version-of-data.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-normalized-version-of-data.md b/python/sort-normalized-version-of-data.md new file mode 100644 index 0000000..a6b2243 --- /dev/null +++ b/python/sort-normalized-version-of-data.md @@ -0,0 +1,33 @@ +# Sort Normalized Version Of Data + +Let's say I have a list of names that I want to sort. However, because of +inconsistency in how the data was entered, sometimes those names are capitalized +and other times they are not. Using +[`methodcaller`](https://docs.python.org/3/library/operator.html#operator.methodcaller), +I can normalize the sorting `key` used when comparing list items. + +First, let's look at calling `sorted` with the list and no `key`: + +```python +>>> sorted(["butler", "Jemisin", "le guin", "Erdrich"]) +['Erdrich', 'Jemisin', 'butler', 'le guin'] +``` + +`butler` which starts with a `b` gets moved to the 3rd position because it is +lowercase. + +To sort this list using a normalized comparison, we will use `methodcaller` to +create a callable out of `lower` which is then passed as the sort `key`: + +```python +>>> from operator import methodcaller +>>> sorted(["butler", "Jemisin", "le guin", "Erdrich"], key=methodcaller("lower")) +['butler', 'Erdrich', 'Jemisin', 'le guin'] +``` + +That's the sort order I was originally hoping for. + +What `methodcaller` is doing is creating a callable function that will invoke +`lower` with each string instance as the target. Conceptually similar to +`"Erdrich".lower()` or even `getattr("Erdrich", "lower")()` (notice this needs +to be immediately invoked).