0
# Key Generation Functions
1
2
Functions for generating reusable sorting key functions that can be used with Python's built-in sorting functions. This approach is more efficient when you need to sort multiple times with the same algorithm, as it pre-computes the sorting logic.
3
4
## Capabilities
5
6
### Natural Sort Key Generation
7
8
Generate a key function for natural sorting that can be reused with built-in sorting functions.
9
10
```python { .api }
11
def natsort_keygen(key=None, alg=ns.DEFAULT):
12
"""
13
Generate a key to sort strings and numbers naturally.
14
15
This key is designed for use as the 'key' argument to functions
16
such as the sorted() builtin or list.sort().
17
18
Parameters:
19
- key: callable, optional - A key function applied before parsing for numbers
20
- alg: ns enum, optional - Algorithm control flags (default: ns.DEFAULT)
21
22
Returns:
23
Callable - A function suitable for use as a sorting key
24
25
Examples:
26
>>> key_func = natsort_keygen()
27
>>> sorted(['num10', 'num2', 'num1'], key=key_func)
28
['num1', 'num2', 'num10']
29
30
>>> # Custom algorithm with case-insensitive real numbers
31
>>> key_func = natsort_keygen(alg=ns.REAL | ns.IGNORECASE)
32
>>> data = ['Item-5.2', 'item10.1', 'ITEM2.7']
33
>>> sorted(data, key=key_func)
34
['Item-5.2', 'ITEM2.7', 'item10.1']
35
"""
36
```
37
38
### Default Natural Sort Key
39
40
Pre-generated natural sort key function using default settings.
41
42
```python { .api }
43
natsort_key: Callable[[Any], Tuple[Any, ...]]
44
"""
45
The default natural sorting key.
46
47
This is the output of natsort_keygen() with default values.
48
Equivalent to natsort_keygen() but pre-computed for efficiency.
49
50
Examples:
51
>>> sorted(['num10', 'num2', 'num1'], key=natsort_key)
52
['num1', 'num2', 'num10']
53
"""
54
```
55
56
### OS Sort Key Generation
57
58
Generate a key function that replicates your operating system's file browser sort order.
59
60
```python { .api }
61
def os_sort_keygen(key=None):
62
"""
63
Generate a sorting key to replicate your file browser's sort order.
64
65
Creates platform-specific sorting keys that match the behavior of
66
file explorers on different operating systems.
67
68
Parameters:
69
- key: callable, optional - A key function applied before OS sorting
70
71
Returns:
72
Callable - A function suitable for OS-native path sorting
73
74
Notes:
75
- On Windows: Uses StrCmpLogicalW API for Explorer-compatible sorting
76
- On macOS/Linux: Uses ICU collation if available, otherwise locale-based
77
- Results will differ intentionally between platforms
78
"""
79
```
80
81
### Default OS Sort Key
82
83
Pre-generated OS sort key function using default settings.
84
85
```python { .api }
86
os_sort_key: Callable[[Any], Tuple[Any, ...]]
87
"""
88
The default key to replicate your file browser's sort order.
89
90
This is the output of os_sort_keygen() with default values.
91
Platform-specific implementation for consistent OS behavior.
92
93
Examples:
94
>>> import os
95
>>> files = os.listdir('.')
96
>>> sorted(files, key=os_sort_key) # Matches file browser order
97
"""
98
```
99
100
## Usage Examples
101
102
### Performance Benefits with Repeated Sorting
103
104
```python
105
from natsort import natsort_keygen, ns
106
import time
107
108
# Large dataset for performance testing
109
data = [f'item{i}' for i in range(10000, 0, -1)] # ['item10000', 'item9999', ...]
110
111
# Method 1: Using natsorted (recreates key function each time)
112
start_time = time.time()
113
for _ in range(100):
114
from natsort import natsorted
115
result = natsorted(data)
116
end_time = time.time()
117
print(f"natsorted method: {end_time - start_time:.4f} seconds")
118
119
# Method 2: Using pre-generated key (more efficient for repeated sorting)
120
key_func = natsort_keygen()
121
start_time = time.time()
122
for _ in range(100):
123
result = sorted(data, key=key_func)
124
end_time = time.time()
125
print(f"key generation method: {end_time - start_time:.4f} seconds")
126
```
127
128
### In-Place Sorting with Generated Keys
129
130
```python
131
from natsort import natsort_keygen, ns
132
133
# Sort a list in-place using a generated key
134
file_list = ['file10.txt', 'file2.txt', 'file1.txt', 'file20.txt']
135
print(f"Original: {file_list}")
136
137
# Create a key function for natural sorting
138
nat_key = natsort_keygen()
139
file_list.sort(key=nat_key)
140
print(f"Sorted in-place: {file_list}")
141
142
# Sort with custom algorithm (case-insensitive, real numbers)
143
mixed_data = ['Value-5.2', 'value10.1', 'VALUE2.7']
144
print(f"Original mixed: {mixed_data}")
145
146
real_key = natsort_keygen(alg=ns.REAL | ns.IGNORECASE)
147
mixed_data.sort(key=real_key)
148
print(f"Sorted mixed: {mixed_data}")
149
```
150
151
### Custom Key Functions with Transform
152
153
```python
154
from natsort import natsort_keygen
155
from pathlib import Path
156
157
# Sort file paths by filename only, ignoring directory structure
158
paths = [
159
'/home/user/documents/file10.txt',
160
'/var/log/file2.txt',
161
'/tmp/file1.txt',
162
'/home/user/file20.txt'
163
]
164
165
# Create a key that extracts filename before natural sorting
166
filename_key = natsort_keygen(key=lambda x: Path(x).name)
167
168
sorted_paths = sorted(paths, key=filename_key)
169
print("Sorted by filename:")
170
for path in sorted_paths:
171
print(f" {path}")
172
173
# Sort by file extension, then by natural order of filename
174
def extension_then_name(path):
175
p = Path(path)
176
return (p.suffix, p.stem) # Sort by extension first, then stem
177
178
ext_key = natsort_keygen(key=extension_then_name)
179
180
files = ['document.pdf', 'image10.jpg', 'image2.jpg', 'readme.txt', 'data.pdf']
181
sorted_by_ext = sorted(files, key=ext_key)
182
print(f"Sorted by extension then name: {sorted_by_ext}")
183
```
184
185
### OS-Compatible File Sorting
186
187
```python
188
from natsort import os_sort_keygen
189
import os
190
from pathlib import Path
191
192
# Get current directory files
193
current_dir = Path('.')
194
files = [f.name for f in current_dir.iterdir() if f.is_file()]
195
196
# Sort using OS-native ordering (matches file browser)
197
os_key = os_sort_keygen()
198
os_sorted_files = sorted(files, key=os_key)
199
200
print("Files sorted in OS-native order:")
201
for filename in os_sorted_files[:10]: # Show first 10
202
print(f" {filename}")
203
204
# Compare with regular natural sorting
205
from natsort import natsort_key
206
nat_sorted_files = sorted(files, key=natsort_key)
207
208
print("\nDifferences between OS and natural sorting:")
209
for i, (os_file, nat_file) in enumerate(zip(os_sorted_files, nat_sorted_files)):
210
if os_file != nat_file:
211
print(f" Position {i}: OS='{os_file}' vs Natural='{nat_file}'")
212
```
213
214
### Advanced Algorithm Combinations
215
216
```python
217
from natsort import natsort_keygen, ns
218
219
# Complex data requiring multiple algorithm flags
220
scientific_data = [
221
'Experiment-1.5E+10_ResultA',
222
'experiment-2.3e-5_resultB',
223
'EXPERIMENT-1.2E+3_resultC',
224
'Experiment-5.0_resultD'
225
]
226
227
# Combine multiple algorithm flags:
228
# - REAL: handle signed floats and scientific notation
229
# - IGNORECASE: case-insensitive comparison
230
# - LOWERCASEFIRST: lowercase items come first
231
complex_key = natsort_keygen(
232
alg=ns.REAL | ns.IGNORECASE | ns.LOWERCASEFIRST
233
)
234
235
sorted_scientific = sorted(scientific_data, key=complex_key)
236
print("Scientific data sorted with complex algorithm:")
237
for item in sorted_scientific:
238
print(f" {item}")
239
240
# Using path-specific sorting for nested directory structures
241
paths = [
242
'data/experiment1/result10.txt',
243
'data/experiment1/result2.txt',
244
'data/experiment10/result1.txt',
245
'data/experiment2/result1.txt'
246
]
247
248
path_key = natsort_keygen(alg=ns.PATH)
249
sorted_paths = sorted(paths, key=path_key)
250
print("\nPaths sorted with PATH algorithm:")
251
for path in sorted_paths:
252
print(f" {path}")
253
```
254
255
### Reusable Keys for Different Data Types
256
257
```python
258
from natsort import natsort_keygen, ns
259
260
# Create different specialized keys for different data types
261
version_key = natsort_keygen(alg=ns.FLOAT) # For version strings like "1.2.10"
262
filename_key = natsort_keygen(alg=ns.PATH | ns.IGNORECASE) # For filenames
263
human_key = natsort_keygen(alg=ns.LOCALE | ns.IGNORECASE) # For human-readable text
264
265
# Version strings
266
versions = ['v1.2.10', 'v1.2.2', 'v1.10.1', 'v2.0.0']
267
print(f"Versions: {sorted(versions, key=version_key)}")
268
269
# Filenames (case-insensitive, path-aware)
270
filenames = ['README.txt', 'src/main.py', 'src/utils.py', 'tests/test_main.py']
271
print(f"Files: {sorted(filenames, key=filename_key)}")
272
273
# Human text (locale-aware, case-insensitive)
274
names = ['Müller', 'müller', 'Anderson', 'Åberg']
275
print(f"Names: {sorted(names, key=human_key)}")
276
```