# python – Is there a built in function for string natural sort?

## python – Is there a built in function for string natural sort?

There is a third party library for this on PyPI called natsort (full disclosure, I am the packages author). For your case, you can do either of the following:

``````>>> from natsort import natsorted, ns
>>> x = [Elm11, Elm12, Elm2, elm0, elm1, elm10, elm13, elm9]
>>> natsorted(x, key=lambda y: y.lower())
[elm0, elm1, Elm2, elm9, elm10, Elm11, Elm12, elm13]
>>> natsorted(x, alg=ns.IGNORECASE)  # or alg=ns.IC
[elm0, elm1, Elm2, elm9, elm10, Elm11, Elm12, elm13]
``````

You should note that `natsort` uses a general algorithm so it should work for just about any input that you throw at it. If you want more details on why you might choose a library to do this rather than rolling your own function, check out the `natsort` documentations How It Works page, in particular the Special Cases Everywhere! section.

If you need a sorting key instead of a sorting function, use either of the below formulas.

``````>>> from natsort import natsort_keygen, ns
>>> l1 = [elm0, elm1, Elm2, elm9, elm10, Elm11, Elm12, elm13]
>>> l2 = l1[:]
>>> natsort_key1 = natsort_keygen(key=lambda y: y.lower())
>>> l1.sort(key=natsort_key1)
>>> l1
[elm0, elm1, Elm2, elm9, elm10, Elm11, Elm12, elm13]
>>> natsort_key2 = natsort_keygen(alg=ns.IGNORECASE)
>>> l2.sort(key=natsort_key2)
>>> l2
[elm0, elm1, Elm2, elm9, elm10, Elm11, Elm12, elm13]
``````

Update November 2020

Given that a popular request/question is how to sort like Windows Explorer? (or whatever is your operating systems file system browser), as of `natsort` version 7.1.0 there is a function called `os_sorted` to do exactly this. On Windows, it will sort in the same order as Windows Explorer, and on other operating systems it should sort like whatever is the local file system browser.

``````>>> from natsort import os_sorted
>>> os_sorted(list_of_paths)
``````

For those needing a sort key, you can use `os_sort_keygen` (or `os_sort_key` if you just need the defaults).

Caveat – Please read the API documentation for this function before you use to understand the limitations and how to get best results.

Try this:

``````import re

def natural_sort(l):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split(([0-9]+), key)]
return sorted(l, key=alphanum_key)
``````

Output:

``````[elm0, elm1, Elm2, elm9, elm10, Elm11, Elm12, elm13]
``````

Code adapted from here: Sorting for Humans : Natural Sort Order.

#### python – Is there a built in function for string natural sort?

Heres a much more pythonic version of Mark Byers answer:

``````import re

def natural_sort_key(s, _nsre=re.compile(([0-9]+))):
return [int(text) if text.isdigit() else text.lower()
for text in _nsre.split(s)]
``````

Now this function can be used as a key in any function that uses it, like `list.sort`, `sorted`, `max`, etc.

As a lambda:

``````lambda s: [int(t) if t.isdigit() else t.lower() for t in re.split((d+), s)]
``````

Fully reproducible demo code:

``````import re
natsort = lambda s: [int(t) if t.isdigit() else t.lower() for t in re.split((d+), s)]
L = [a1, a10, a11, a2, a22, a3]
print(sorted(L, key=natsort))
# [a1, a2, a3, a10, a11, a22]
``````