0
# Index-Based Sorting
1
2
Functions that return sorted indexes rather than sorted sequences, enabling you to sort multiple related sequences by the sort order of one sequence. This is useful when you have related data stored in separate lists that need to be sorted together.
3
4
## Capabilities
5
6
### Natural Index Sorting
7
8
Returns the list of indexes that would sort the input sequence naturally.
9
10
```python { .api }
11
def index_natsorted(seq, key=None, reverse=False, alg=ns.DEFAULT):
12
"""
13
Determine the list of indexes used to sort the input sequence.
14
15
Sorts a sequence naturally, but returns a list of the sorted indexes
16
instead of the sorted list itself.
17
18
Parameters:
19
- seq: iterable - The input to sort
20
- key: callable, optional - A key function to determine sorting
21
- reverse: bool, optional - Return in reversed order (default: False)
22
- alg: ns enum, optional - Algorithm control flags (default: ns.DEFAULT)
23
24
Returns:
25
List[int] - The ordered indexes of the input
26
27
Examples:
28
>>> index_natsorted(['num3', 'num5', 'num2'])
29
[2, 0, 1]
30
"""
31
```
32
33
### Human-Friendly Index Sorting
34
35
Returns indexes for locale-aware sorting order.
36
37
```python { .api }
38
def index_humansorted(seq, key=None, reverse=False, alg=ns.DEFAULT):
39
"""
40
This is a wrapper around index_natsorted(seq, alg=ns.LOCALE).
41
42
Parameters:
43
- seq: iterable - The input to sort
44
- key: callable, optional - A key function to determine sorting
45
- reverse: bool, optional - Return in reversed order (default: False)
46
- alg: ns enum, optional - Additional algorithm flags (default: ns.DEFAULT)
47
48
Returns:
49
List[int] - The ordered indexes of the input using locale-aware sorting
50
51
Examples:
52
>>> index_humansorted(['Apple', 'Banana', 'apple', 'banana'])
53
[2, 0, 3, 1]
54
"""
55
```
56
57
### Real Number Index Sorting
58
59
Returns indexes for signed float sorting order.
60
61
```python { .api }
62
def index_realsorted(seq, key=None, reverse=False, alg=ns.DEFAULT):
63
"""
64
This is a wrapper around index_natsorted(seq, alg=ns.REAL).
65
66
Parameters:
67
- seq: iterable - The input to sort
68
- key: callable, optional - A key function to determine sorting
69
- reverse: bool, optional - Return in reversed order (default: False)
70
- alg: ns enum, optional - Additional algorithm flags (default: ns.DEFAULT)
71
72
Returns:
73
List[int] - The ordered indexes with proper signed float handling
74
75
Examples:
76
>>> index_realsorted(['num5.10', 'num-3', 'num5.3', 'num2'])
77
[1, 3, 0, 2]
78
"""
79
```
80
81
### Order by Index
82
83
Order a given sequence by an index sequence, typically used with the output from index_* functions.
84
85
```python { .api }
86
def order_by_index(seq, index, iter=False):
87
"""
88
Order a given sequence by an index sequence.
89
90
Apply the ordering specified by an index list to reorder a sequence.
91
92
Parameters:
93
- seq: sequence - The sequence to order
94
- index: iterable - The iterable indicating how to order seq (integers only)
95
- iter: bool, optional - Return as iterator if True, list if False (default: False)
96
97
Returns:
98
List or Iterator - The sequence ordered by index
99
100
Examples:
101
>>> order_by_index(['a', 'b', 'c'], [2, 0, 1])
102
['c', 'a', 'b']
103
"""
104
```
105
106
## Usage Examples
107
108
### Sorting Multiple Related Lists
109
110
```python
111
from natsort import index_natsorted, order_by_index
112
113
# Multiple related data lists
114
names = ['item10', 'item2', 'item1', 'item20']
115
prices = [29.99, 15.50, 9.99, 45.00]
116
categories = ['electronics', 'books', 'toys', 'electronics']
117
118
# Get the natural sort order indexes for names
119
sort_index = index_natsorted(names)
120
print(f"Sort indexes: {sort_index}") # [2, 1, 0, 3]
121
122
# Apply the same ordering to all related lists
123
sorted_names = order_by_index(names, sort_index)
124
sorted_prices = order_by_index(prices, sort_index)
125
sorted_categories = order_by_index(categories, sort_index)
126
127
print(f"Names: {sorted_names}") # ['item1', 'item2', 'item10', 'item20']
128
print(f"Prices: {sorted_prices}") # [9.99, 15.50, 29.99, 45.00]
129
print(f"Categories: {sorted_categories}") # ['toys', 'books', 'electronics', 'electronics']
130
```
131
132
### Working with Complex Data Structures
133
134
```python
135
from natsort import index_natsorted, order_by_index
136
137
# Data stored in separate lists (simulating database columns)
138
ids = ['user10', 'user2', 'user1', 'user20']
139
names = ['Alice Johnson', 'Bob Smith', 'Charlie Brown', 'Diana Wilson']
140
scores = [85, 92, 78, 96]
141
timestamps = ['2023-01-15', '2023-01-10', '2023-01-05', '2023-01-20']
142
143
# Sort all data by natural order of user IDs
144
user_order = index_natsorted(ids)
145
146
# Apply consistent ordering across all data
147
ordered_data = {
148
'ids': order_by_index(ids, user_order),
149
'names': order_by_index(names, user_order),
150
'scores': order_by_index(scores, user_order),
151
'timestamps': order_by_index(timestamps, user_order)
152
}
153
154
print("Ordered by user ID:")
155
for i in range(len(ids)):
156
print(f"{ordered_data['ids'][i]}: {ordered_data['names'][i]} "
157
f"(Score: {ordered_data['scores'][i]}, Date: {ordered_data['timestamps'][i]})")
158
```
159
160
### Performance with Iterator Option
161
162
```python
163
from natsort import order_by_index
164
165
large_data = list(range(1000000)) # Large dataset
166
sort_indexes = [999999, 0, 500000, 1, 999998] # Some specific ordering
167
168
# Get results as iterator for memory efficiency
169
ordered_iter = order_by_index(large_data, sort_indexes, iter=True)
170
171
# Process results one at a time
172
for item in ordered_iter:
173
print(f"Processing: {item}")
174
# Process without loading entire result into memory
175
break # Just showing first item
176
```
177
178
### Reverse Sorting and Custom Keys
179
180
```python
181
from natsort import index_natsorted, order_by_index
182
183
# Sorting file paths by filename (ignoring directory)
184
file_paths = [
185
'/home/user/file10.txt',
186
'/home/user/file2.txt',
187
'/home/user/file1.txt',
188
'/home/user/file20.txt'
189
]
190
191
# Get indexes for reverse natural sort by filename only
192
indexes = index_natsorted(
193
file_paths,
194
key=lambda x: x.split('/')[-1], # Extract filename
195
reverse=True
196
)
197
198
# Apply the ordering
199
sorted_paths = order_by_index(file_paths, indexes)
200
print(sorted_paths)
201
# Output: ['/home/user/file20.txt', '/home/user/file10.txt',
202
# '/home/user/file2.txt', '/home/user/file1.txt']
203
```
204
205
### Working with Real Numbers
206
207
```python
208
from natsort import index_realsorted, order_by_index
209
210
# Scientific data with positive and negative values
211
measurements = ['temp-5.2C', 'temp10.1C', 'temp-12.5C', 'temp2.7C']
212
locations = ['Station A', 'Station B', 'Station C', 'Station D']
213
timestamps = ['10:00', '10:15', '10:30', '10:45']
214
215
# Sort by temperature value (handling negative numbers)
216
temp_order = index_realsorted(measurements)
217
218
print("Sorted by temperature (coldest first):")
219
ordered_measurements = order_by_index(measurements, temp_order)
220
ordered_locations = order_by_index(locations, temp_order)
221
ordered_timestamps = order_by_index(timestamps, temp_order)
222
223
for i in range(len(measurements)):
224
print(f"{ordered_measurements[i]} at {ordered_locations[i]} ({ordered_timestamps[i]})")
225
# Output: temp-12.5C at Station C (10:30)
226
# temp-5.2C at Station A (10:00)
227
# temp2.7C at Station D (10:45)
228
# temp10.1C at Station B (10:15)
229
```