Simple yet flexible natural sorting in Python that enables developers to sort strings containing numbers in a natural, human-expected order rather than lexicographical order.
—
Primary sorting functions that provide natural ordering for different data types and use cases. These functions serve as drop-in replacements for Python's built-in sorted() function but with natural number ordering.
Sorts an iterable naturally, treating numbers within strings as their numeric values rather than lexicographically.
def natsorted(seq, key=None, reverse=False, alg=ns.DEFAULT):
"""
Sorts an iterable naturally.
Parameters:
- seq: iterable - The input to sort
- key: callable, optional - A key function to determine sorting
- reverse: bool, optional - Return in reversed order (default: False)
- alg: ns enum, optional - Algorithm control flags (default: ns.DEFAULT)
Returns:
List - The sorted input
Examples:
>>> natsorted(['num3', 'num5', 'num2'])
['num2', 'num3', 'num5']
>>> natsorted(['version1.10', 'version1.2', 'version1.9'])
['version1.2', 'version1.9', 'version1.10']
"""Convenience function for locale-aware sorting that properly handles non-ASCII characters and follows human sorting expectations.
def humansorted(seq, key=None, reverse=False, alg=ns.DEFAULT):
"""
Convenience function to properly sort non-numeric characters.
This is a wrapper around natsorted(seq, alg=ns.LOCALE).
Parameters:
- seq: iterable - The input to sort
- key: callable, optional - A key function to determine sorting
- reverse: bool, optional - Return in reversed order (default: False)
- alg: ns enum, optional - Additional algorithm flags (default: ns.DEFAULT)
Returns:
List - The sorted input with locale-aware character ordering
Examples:
>>> humansorted(['Apple', 'Banana', 'apple', 'banana'])
['apple', 'Apple', 'banana', 'Banana']
Notes:
Locale support varies by system. Install PyICU for best results.
"""Convenience function for properly sorting strings containing signed floating point numbers.
def realsorted(seq, key=None, reverse=False, alg=ns.DEFAULT):
"""
Convenience function to properly sort signed floats.
A signed float in a string could be "a-5.7". This is a wrapper around
natsorted(seq, alg=ns.REAL).
Parameters:
- seq: iterable - The input to sort
- key: callable, optional - A key function to determine sorting
- reverse: bool, optional - Return in reversed order (default: False)
- alg: ns enum, optional - Additional algorithm flags (default: ns.DEFAULT)
Returns:
List - The sorted input with proper signed float handling
Examples:
>>> realsorted(['num5.10', 'num-3', 'num5.3', 'num2'])
['num-3', 'num2', 'num5.10', 'num5.3']
"""Sort elements in the same order as your operating system's file browser, providing OS-native file ordering.
def os_sorted(seq, key=None, reverse=False, presort=False):
"""
Sort elements in the same order as your operating system's file browser.
Platform-specific sorting that matches file explorer behavior on Windows,
macOS, and Linux systems.
Parameters:
- seq: iterable - The input to sort (each element must be str-like)
- key: callable, optional - A key function to determine sorting
- reverse: bool, optional - Return in reversed order (default: False)
- presort: bool, optional - Pre-sort as strings first (default: False)
Returns:
List - The sorted input in OS-native file browser order
Examples:
>>> os_sorted(['file10.txt', 'file2.txt', 'File1.txt'])
# Result varies by operating system
Notes:
- On Windows: Uses Windows Explorer sorting via StrCmpLogicalW
- On macOS/Linux: Uses ICU collation if available, falls back to locale-aware sorting
- Results intentionally differ between platforms to match OS behavior
- Install PyICU on macOS/Linux for best results
"""from natsort import natsorted
# File names with numbers
files = ['file1.txt', 'file10.txt', 'file2.txt', 'file20.txt']
print(natsorted(files))
# Output: ['file1.txt', 'file2.txt', 'file10.txt', 'file20.txt']
# Version strings
versions = ['v1.0.10', 'v1.0.2', 'v1.0.1', 'v1.1.0']
print(natsorted(versions))
# Output: ['v1.0.1', 'v1.0.2', 'v1.0.10', 'v1.1.0']from natsort import natsorted, ns
# Case-insensitive sorting
mixed_case = ['Item1', 'item10', 'Item2', 'item20']
print(natsorted(mixed_case, alg=ns.IGNORECASE))
# Output: ['Item1', 'Item2', 'item10', 'item20']
# Float number handling
floats = ['value1.5', 'value1.10', 'value1.05']
print(natsorted(floats, alg=ns.FLOAT))
# Output: ['value1.05', 'value1.5', 'value1.10']
# Path sorting
paths = ['folder/file10.txt', 'folder/file2.txt', 'folder/file1.txt']
print(natsorted(paths, alg=ns.PATH))
# Output: ['folder/file1.txt', 'folder/file2.txt', 'folder/file10.txt']from natsort import natsorted
from pathlib import Path
# Sort by filename only (ignore path)
file_paths = ['/path/to/file10.txt', '/other/file2.txt', '/path/file1.txt']
sorted_by_name = natsorted(file_paths, key=lambda x: Path(x).name)
print(sorted_by_name)
# Output: ['/path/file1.txt', '/other/file2.txt', '/path/to/file10.txt']
# Sort custom objects
class Version:
def __init__(self, version_str):
self.version = version_str
def __repr__(self):
return f"Version('{self.version}')"
versions = [Version('1.10.0'), Version('1.2.0'), Version('1.9.0')]
sorted_versions = natsorted(versions, key=lambda v: v.version)
print(sorted_versions)
# Output: [Version('1.2.0'), Version('1.9.0'), Version('1.10.0')]Install with Tessl CLI
npx tessl i tessl/pypi-natsort