Skip to content

Commit 5fc15a3

Browse files
committed
Add natural_sorted Python function
1 parent 4db83b9 commit 5fc15a3

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ Various code snippets
33

44
This repository contains various code snippet that are used in several places.
55

6+
natural_sorted
7+
--------------
8+
9+
The Python function `natural_sorted` behaves like the built-in function
10+
`sorted`, but it returns a naturally sorted list instead.
11+
612
python_tests
713
------------
814

natural_sorted.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (C) 2018, Benjamin Drung <[email protected]>
2+
#
3+
# Permission to use, copy, modify, and/or distribute this software for any
4+
# purpose with or without fee is hereby granted, provided that the above
5+
# copyright notice and this permission notice appear in all copies.
6+
#
7+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14+
15+
import re
16+
17+
def natural_sorted(iterable, key=None, reverse=False):
18+
"""Return a new naturally sorted list from the items in *iterable*.
19+
20+
The returned list is in natural sort order. The string is ordered
21+
lexicographically (using the Unicode code point number to order individual
22+
characters), except that multi-digit numbers are ordered as a single character.
23+
24+
Has two optional arguments which must be specified as keyword arguments.
25+
26+
*key* specifies a function of one argument that is used to extract a comparison
27+
key from each list element: ``key=str.lower``. The default value is ``None``
28+
(compare the elements directly).
29+
30+
*reverse* is a boolean value. If set to ``True``, then the list elements are
31+
sorted as if each comparison were reversed.
32+
33+
The :func:`natural_sorted` function is guaranteed to be stable. A sort is
34+
stable if it guarantees not to change the relative order of elements that
35+
compare equal --- this is helpful for sorting in multiple passes (for
36+
example, sort by department, then by salary grade).
37+
"""
38+
prog = re.compile(r"(\d+)")
39+
40+
def alphanum_key(element):
41+
"""Split given key in list of strings and digits"""
42+
return [int(c) if c.isdigit() else c for c in prog.split(key(element) if key else element)]
43+
44+
return sorted(iterable, key=alphanum_key, reverse=reverse)

0 commit comments

Comments
 (0)