0
# Algorithm Configuration
1
2
The `ns` enum system provides fine-grained control over natural sorting behavior. Options can be combined using bitwise OR operations to create customized sorting algorithms that handle different data types and cultural conventions.
3
4
## Capabilities
5
6
### Core ns Enum Class
7
8
The main configuration enum that controls natsort algorithm behavior.
9
10
```python { .api }
11
class ns(enum.IntEnum):
12
"""
13
Enum to control the natsort algorithm.
14
15
Options can be combined using bitwise OR (|) operations.
16
Each option has a shortened 1- or 2-letter form.
17
"""
18
19
# Number interpretation (mutually exclusive groups)
20
DEFAULT = 0 # Default behavior
21
INT = I = 0 # Parse numbers as integers (default)
22
UNSIGNED = U = 0 # Ignore signs like +/- (default)
23
FLOAT = F = 1 # Parse numbers as floats
24
SIGNED = S = 2 # Consider +/- signs in numbers
25
REAL = R = 3 # Shortcut for FLOAT | SIGNED
26
NOEXP = N = 4 # Don't parse scientific notation (e.g., 1e4)
27
28
# String and character handling
29
IGNORECASE = IC = 64 # Case-insensitive sorting
30
LOWERCASEFIRST = LF = 128 # Lowercase letters before uppercase
31
GROUPLETTERS = G = 256 # Group upper/lowercase together
32
CAPITALFIRST = C = 512 # Capitalized words first (alias: UNGROUPLETTERS)
33
UNGROUPLETTERS = UG = 512 # Alias for CAPITALFIRST
34
35
# Locale and internationalization
36
LOCALEALPHA = LA = 16 # Locale-aware alphabetical sorting only
37
LOCALENUM = LN = 32 # Locale-aware numeric formatting only
38
LOCALE = L = 48 # Locale-aware sorting (LOCALEALPHA | LOCALENUM)
39
40
# Special handling
41
PATH = P = 8 # Treat strings as filesystem paths
42
NANLAST = NL = 1024 # Place NaN values last instead of first
43
COMPATIBILITYNORMALIZE = CN = 2048 # Use NFKD unicode normalization
44
NUMAFTER = NA = 4096 # Sort numbers after non-numbers
45
PRESORT = PS = 8192 # Pre-sort as strings before natural sorting
46
```
47
48
### Algorithm Type Alias
49
50
Type definition for algorithm specifications.
51
52
```python { .api }
53
NSType = Union[ns, int]
54
"""
55
Type alias for algorithm specification.
56
Accepts either ns enum values or integer combinations.
57
"""
58
```
59
60
## Usage Examples
61
62
### Basic Number Handling Options
63
64
```python
65
from natsort import natsorted, ns
66
67
# Default integer handling
68
data = ['item1', 'item10', 'item2']
69
print(natsorted(data)) # ['item1', 'item2', 'item10']
70
71
# Float number handling
72
float_data = ['value1.5', 'value1.10', 'value1.05']
73
print(natsorted(float_data, alg=ns.FLOAT))
74
# Output: ['value1.05', 'value1.5', 'value1.10']
75
76
# Signed number handling (positive and negative)
77
signed_data = ['temp-5', 'temp10', 'temp-12', 'temp2']
78
print(natsorted(signed_data, alg=ns.SIGNED))
79
# Output: ['temp-12', 'temp-5', 'temp2', 'temp10']
80
81
# Real numbers (float + signed)
82
real_data = ['val-1.5', 'val2.3', 'val-0.8', 'val10.1']
83
print(natsorted(real_data, alg=ns.REAL))
84
# Output: ['val-1.5', 'val-0.8', 'val2.3', 'val10.1']
85
```
86
87
### Case Sensitivity Options
88
89
```python
90
from natsort import natsorted, ns
91
92
mixed_case = ['Item1', 'item10', 'Item2', 'item20']
93
94
# Default (case-sensitive)
95
print("Default:", natsorted(mixed_case))
96
# Output: ['Item1', 'Item2', 'item10', 'item20']
97
98
# Case-insensitive
99
print("Ignore case:", natsorted(mixed_case, alg=ns.IGNORECASE))
100
# Output: ['Item1', 'Item2', 'item10', 'item20']
101
102
# Lowercase first
103
print("Lowercase first:", natsorted(mixed_case, alg=ns.LOWERCASEFIRST))
104
# Output: ['item10', 'item20', 'Item1', 'Item2']
105
106
# Group letters (case-insensitive grouping)
107
print("Group letters:", natsorted(mixed_case, alg=ns.GROUPLETTERS))
108
# Output: ['Item1', 'item10', 'Item2', 'item20']
109
```
110
111
### Path-Specific Sorting
112
113
```python
114
from natsort import natsorted, ns
115
116
# File paths with different extensions and directories
117
paths = [
118
'folder/file10.txt',
119
'folder/file2.txt',
120
'folder/file1.log',
121
'folder/file10.log',
122
'folder/file2.py'
123
]
124
125
# Default sorting
126
print("Default sorting:")
127
for path in natsorted(paths):
128
print(f" {path}")
129
130
# Path-aware sorting (splits on separators and extensions)
131
print("\nPath-aware sorting:")
132
for path in natsorted(paths, alg=ns.PATH):
133
print(f" {path}")
134
```
135
136
### Locale-Aware Sorting
137
138
```python
139
from natsort import natsorted, ns
140
141
# International characters and accents
142
international = ['café', 'naïve', 'résumé', 'Åpfel', 'zebra', 'Zürich']
143
144
# Default sorting (ASCII order)
145
print("Default:", natsorted(international))
146
147
# Locale-aware sorting (requires proper locale setup)
148
print("Locale-aware:", natsorted(international, alg=ns.LOCALE))
149
150
# Locale-aware with case insensitive
151
print("Locale + ignore case:",
152
natsorted(international, alg=ns.LOCALE | ns.IGNORECASE))
153
154
# Note: Results depend on system locale configuration
155
# Install PyICU for best locale support
156
```
157
158
### Advanced Algorithm Combinations
159
160
```python
161
from natsort import natsorted, ns
162
163
# Scientific data with complex requirements
164
scientific_data = [
165
'Sample-1.5E+3_Trial2',
166
'sample-2.1e-4_trial10',
167
'SAMPLE-0.8E+2_trial1',
168
'Sample-3.2_Trial20'
169
]
170
171
# Combine multiple options:
172
# - REAL: handle signed floats and scientific notation
173
# - IGNORECASE: case-insensitive comparison
174
# - LOWERCASEFIRST: lowercase variants come first
175
combined_alg = ns.REAL | ns.IGNORECASE | ns.LOWERCASEFIRST
176
177
sorted_scientific = natsorted(scientific_data, alg=combined_alg)
178
print("Scientific data with combined algorithm:")
179
for item in sorted_scientific:
180
print(f" {item}")
181
```
182
183
### Special Value Handling
184
185
```python
186
from natsort import natsorted, ns
187
import math
188
189
# Data with special values
190
data_with_nan = ['value1', 'value10', None, 'value2', float('nan')]
191
192
# Default NaN handling (NaN comes first)
193
print("Default NaN handling:", natsorted(data_with_nan))
194
195
# NaN last
196
print("NaN last:", natsorted(data_with_nan, alg=ns.NANLAST))
197
198
# Numbers after non-numbers (reverse typical order)
199
mixed_types = ['abc', '10', 'def', '2', 'ghi']
200
print("Default:", natsorted(mixed_types))
201
print("Numbers after:", natsorted(mixed_types, alg=ns.NUMAFTER))
202
```
203
204
### Pre-sorting for Consistency
205
206
```python
207
from natsort import natsorted, ns
208
209
# Data where string representation affects order
210
inconsistent_data = ['a01', 'a1', 'a10', 'a010']
211
212
# Default behavior (may be inconsistent due to string representation)
213
print("Default:", natsorted(inconsistent_data))
214
215
# Pre-sort to ensure consistent ordering
216
print("With presort:", natsorted(inconsistent_data, alg=ns.PRESORT))
217
```
218
219
### Unicode Normalization
220
221
```python
222
from natsort import natsorted, ns
223
224
# Unicode characters that may have different representations
225
unicode_data = ['café', 'cafe\u0301'] # Second has combining accent
226
227
# Default normalization (NFD)
228
print("Default normalization:", natsorted(unicode_data))
229
230
# Compatibility normalization (NFKD) - converts more characters
231
print("Compatibility normalization:",
232
natsorted(unicode_data, alg=ns.COMPATIBILITYNORMALIZE))
233
```
234
235
### Building Complex Algorithms
236
237
```python
238
from natsort import natsorted, ns
239
240
def create_algorithm(**options):
241
"""Helper function to build algorithm from named options."""
242
alg = ns.DEFAULT
243
244
if options.get('float_numbers'):
245
alg |= ns.FLOAT
246
if options.get('signed_numbers'):
247
alg |= ns.SIGNED
248
if options.get('ignore_case'):
249
alg |= ns.IGNORECASE
250
if options.get('locale_aware'):
251
alg |= ns.LOCALE
252
if options.get('path_sorting'):
253
alg |= ns.PATH
254
if options.get('numbers_last'):
255
alg |= ns.NUMAFTER
256
257
return alg
258
259
# Example usage of algorithm builder
260
data = ['File-1.5', 'file10.2', 'FILE2.0']
261
262
# Build custom algorithm
263
custom_alg = create_algorithm(
264
float_numbers=True,
265
signed_numbers=True,
266
ignore_case=True
267
)
268
269
result = natsorted(data, alg=custom_alg)
270
print(f"Custom algorithm result: {result}")
271
272
# Equivalent to:
273
# result = natsorted(data, alg=ns.REAL | ns.IGNORECASE)
274
```
275
276
### Platform-Specific Considerations
277
278
```python
279
from natsort import natsorted, ns
280
import sys
281
282
# Algorithm selection based on platform/locale
283
def get_platform_algorithm():
284
"""Select appropriate algorithm based on platform."""
285
base_alg = ns.REAL | ns.IGNORECASE
286
287
if sys.platform.startswith('win'):
288
# Windows-specific adjustments
289
return base_alg | ns.LOWERCASEFIRST
290
else:
291
# Unix-like systems
292
return base_alg | ns.LOCALE
293
294
platform_alg = get_platform_algorithm()
295
data = ['File1', 'file10', 'File2']
296
result = natsorted(data, alg=platform_alg)
297
print(f"Platform-optimized result: {result}")
298
```