Unnecessary else:
if length <= 1: return arr else: pivot = arr.pop() ...
If the first path is taken, the method exits. If the second path is taken, then execution continues with the remainder of the method. So you could write the rest of the method inside the else:
clause:
if length <= 1: return arr else: pivot = arr.pop() ... # Now part of the else statement
Or, for more "left leaning" code, remove the else:
clause altogether:
if length <= 1: return arr pivot = arr.pop() ...
Loop like a native
items_greater = [] items_lower = [] for item in arr: if item > pivot: items_greater.append(item) else: items_lower.append(item)
Here, you are creating a list, and then calling .append()
to repeatedly add items to that list in a loop. Python has a builtin mechanism to do this, faster. List comprehension:
items_greater = [item for item in arr if item > pivot] items_lower = [item for item in arr if not(item > pivot)]
Why not(item > pivot)
, and not simply item <= pivot
? For the most part, the latter will work. But there are gotchas and special cases. If there are infinities (+Inf
, -Inf
) or a not-a-numbers (NaN
) in the list, items might be omitted from both lists. For example, if the list contains a NaN
, both NaN > 10
and NaN <= 10
are False
, which would result in that item not being added to either the items_greater
or the items_lower
lists! Worse, if pivot
happened to become NaN
, then all arr
items would be excluded! Similarly, if there are two infinities in the list, both +Inf > +Inf
and +Inf <= +Inf
are False
.
PEP-8
The PEP-8 coding standard has many suggestion about how to format code. Binary operators, for example, should have a single space on either side of the binary operator.
return quick_sort(items_lower)+[pivot]+quick_sort(items_greater)
should be:
return quick_sort(items_lower) + [pivot] + quick_sort(items_greater)