Skip to content

Commit 1dde6ed

Browse files
Type recursive quick sort for any comparable items
Part of #15234
1 parent ef2ecc4 commit 1dde6ed

1 file changed

Lines changed: 46 additions & 9 deletions

File tree

‎sorts/recursive_quick_sort.py‎

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,56 @@
1-
def quick_sort(data: list) -> list:
2-
"""
3-
>>> for data in ([2, 1, 0], [2.2, 1.1, 0], "quick_sort"):
1+
"""
2+
A pure Python implementation of a recursive quick sort.
3+
4+
For doctests run the following command:
5+
python3 -m doctest -v recursive_quick_sort.py
6+
7+
For manual testing run:
8+
python3 recursive_quick_sort.py
9+
"""
10+
11+
from typing import Any, Protocol
12+
13+
14+
class Comparable(Protocol):
15+
def __lt__(self, other: Any, /) -> bool: ...
16+
17+
18+
def quick_sort[T: Comparable](data: list[T]) -> list[T]:
19+
"""Sort a list of mutually comparable items with recursive quick sort.
20+
21+
Returns a new list. Items must be mutually orderable. Mixing types that
22+
cannot be compared raises ``TypeError`` instead of returning a silently
23+
wrong order.
24+
25+
Examples:
26+
>>> quick_sort([2, 1, 0])
27+
[0, 1, 2]
28+
>>> quick_sort([2.2, 1.1, 0])
29+
[0, 1.1, 2.2]
30+
>>> quick_sort(["c", "a", "b"])
31+
['a', 'b', 'c']
32+
>>> quick_sort([])
33+
[]
34+
>>> quick_sort([2.5, -1, 0.0]) == sorted([2.5, -1, 0.0])
35+
True
36+
>>> quick_sort(list("quick_sort")) == sorted("quick_sort")
37+
True
38+
>>> import pytest
39+
>>> with pytest.raises(TypeError):
40+
... quick_sort([1, "a"])
41+
>>> for data in ([2, 1, 0], [2.2, 1.1, 0], list("quick_sort")):
442
... quick_sort(data) == sorted(data)
543
True
644
True
745
True
846
"""
947
if len(data) <= 1:
1048
return data
11-
else:
12-
return [
13-
*quick_sort([e for e in data[1:] if e <= data[0]]),
14-
data[0],
15-
*quick_sort([e for e in data[1:] if e > data[0]]),
16-
]
49+
return [
50+
*quick_sort([item for item in data[1:] if item <= data[0]]),
51+
data[0],
52+
*quick_sort([item for item in data[1:] if item > data[0]]),
53+
]
1754

1855

1956
if __name__ == "__main__":

0 commit comments

Comments
 (0)