|
25 | 25 | python power_sort.py |
26 | 26 | """ |
27 | 27 |
|
28 | | -from __future__ import annotations |
29 | | - |
30 | | -from collections.abc import Callable |
| 28 | +from collections.abc import Callable, Iterable |
31 | 29 | from typing import Any |
32 | 30 |
|
33 | 31 |
|
34 | | -def _find_run( |
35 | | - arr: list, start: int, end: int, key: Callable[[Any], Any] | None = None |
| 32 | +def _find_run[T]( |
| 33 | + arr: list[T], start: int, end: int, key: Callable[[Any], Any] | None = None |
36 | 34 | ) -> int: |
37 | 35 | """ |
38 | 36 | Detect a run (ascending or descending sequence) starting at 'start'. |
@@ -67,7 +65,7 @@ def _find_run( |
67 | 65 | if start >= end - 1: |
68 | 66 | return start + 1 |
69 | 67 |
|
70 | | - key_func = key if key else lambda element: element |
| 68 | + key_func = key or (lambda element: element) |
71 | 69 | run_end = start + 1 |
72 | 70 |
|
73 | 71 | # Check if run is ascending or descending |
@@ -134,8 +132,8 @@ def _node_power(total_length: int, b1: int, n1: int, b2: int, n2: int) -> int: |
134 | 132 | return power |
135 | 133 |
|
136 | 134 |
|
137 | | -def _merge( |
138 | | - arr: list, |
| 135 | +def _merge[T]( |
| 136 | + arr: list[T], |
139 | 137 | start1: int, |
140 | 138 | end1: int, |
141 | 139 | end2: int, |
@@ -165,7 +163,7 @@ def _merge( |
165 | 163 | >>> arr |
166 | 164 | [1, 2, 3, 5, 6, 7] |
167 | 165 | """ |
168 | | - key_func = key if key else lambda element: element |
| 166 | + key_func = key or (lambda element: element) |
169 | 167 |
|
170 | 168 | # Copy the runs to temporary storage |
171 | 169 | left = arr[start1:end1] |
@@ -196,12 +194,12 @@ def _merge( |
196 | 194 | k += 1 |
197 | 195 |
|
198 | 196 |
|
199 | | -def power_sort( |
200 | | - collection: list, |
| 197 | +def power_sort[T]( |
| 198 | + collection: Iterable[T], |
201 | 199 | *, |
202 | 200 | key: Callable[[Any], Any] | None = None, |
203 | 201 | reverse: bool = False, |
204 | | -) -> list: |
| 202 | +) -> list[T]: |
205 | 203 | """ |
206 | 204 | Sort a list using the PowerSort algorithm. |
207 | 205 |
|
@@ -243,26 +241,38 @@ def power_sort( |
243 | 241 | ['apple', 'banana', 'cherry'] |
244 | 242 | >>> power_sort([3.14, 2.71, 1.41, 1.73]) |
245 | 243 | [1.41, 1.73, 2.71, 3.14] |
| 244 | + >>> power_sort(value for value in [3, 1, 2]) # list |
| 245 | + [1, 2, 3] |
| 246 | + >>> power_sort(value for value in (3, 1, 2)) # tuple |
| 247 | + [1, 2, 3] |
246 | 248 | >>> power_sort([5, 2, 8, 1, 9], reverse=True) |
247 | 249 | [9, 8, 5, 2, 1] |
| 250 | + >>> power_sort(['apple', 'pie', 'a', 'longer']) |
| 251 | + ['a', 'apple', 'longer', 'pie'] |
248 | 252 | >>> power_sort(['apple', 'pie', 'a', 'longer'], key=len) |
249 | 253 | ['a', 'pie', 'apple', 'longer'] |
| 254 | + >>> power_sort(['apple', 'pie', 'a', 'longer'], reverse=True) |
| 255 | + ['pie', 'longer', 'apple', 'a'] |
| 256 | + >>> power_sort(['apple', 'pie', 'a', 'longer'], key=len, reverse=True) # Fix me! |
| 257 | + ['a', 'pie', 'apple', 'longer'] |
250 | 258 | >>> power_sort([(1, 'b'), (2, 'a'), (1, 'a')], key=lambda x: x[0]) |
251 | 259 | [(1, 'b'), (1, 'a'), (2, 'a')] |
252 | 260 | >>> power_sort([1, 2, 3, 2, 1, 2, 3, 4]) |
253 | 261 | [1, 1, 2, 2, 2, 3, 3, 4] |
254 | | - >>> result = power_sort(list(range(100))) |
255 | | - >>> result == list(range(100)) |
| 262 | + >>> power_sort(list(range(100))) == list(range(100)) |
256 | 263 | True |
257 | | - >>> result = power_sort(list(reversed(range(50)))) |
258 | | - >>> result == list(range(50)) |
| 264 | + >>> power_sort(list(reversed(range(50)))) == list(range(50)) |
259 | 265 | True |
| 266 | + >>> power_sort([1, "a"]) |
| 267 | + Traceback (most recent call last): |
| 268 | + ... |
| 269 | + TypeError: '<' not supported between instances of 'str' and 'int' |
260 | 270 | """ |
261 | | - if len(collection) <= 1: |
262 | | - return collection |
263 | | - |
264 | | - # Make a copy to avoid modifying the original if it's immutable |
| 271 | + # Make a copy so any iterable is accepted and the original is not modified. |
265 | 272 | arr = list(collection) |
| 273 | + if len(arr) <= 1: |
| 274 | + return arr |
| 275 | + |
266 | 276 | total_length = len(arr) |
267 | 277 |
|
268 | 278 | # Adjust key function for reverse sorting |
|
0 commit comments