-
-
Notifications
You must be signed in to change notification settings - Fork 46.6k
/
Copy pathnatural_sort.py
41 lines (28 loc) · 1.22 KB
/
natural_sort.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from __future__ import annotations
import re
def natural_sort(input_list: list[str]) -> list[str]:
"""
Sort the given list of strings in the way that humans expect.
The normal python sort algorithm sorts lexicographically,
so you might not get the results that you expect
>>> example1 = ['2 ft 7 in', '1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '7 ft 6 in']
>>> example2 = ['Elm11', 'Elm12', 'Elm2', 'elm0', 'elm1', 'elm10', 'elm13', 'elm9']
>>> sorted(example1)
['1 ft 5 in', '10 ft 2 in', '2 ft 11 in', '2 ft 7 in', '7 ft 6 in']
>>> sorted(example2)
['Elm11', 'Elm12', 'Elm2', 'elm0', 'elm1', 'elm10', 'elm13', 'elm9']
The natural sort algorithm sort based on meaning and not computer code point.
>>> natural_sort(example1)
['1 ft 5 in', '2 ft 7 in', '2 ft 11 in', '7 ft 6 in', '10 ft 2 in']
>>> natural_sort(example2)
['elm0', 'elm1', 'Elm2', 'elm9', 'elm10', 'Elm11', 'Elm12', 'elm13']
"""
def alphanum_key(key):
return [
int(text) if text.isdigit() else text.lower()
for text in re.split("([0-9]+)", key)
]
return sorted(input_list, key=alphanum_key)
if __name__ == "__main__":
import doctest
doctest.testmod()