You misreported the error; it doesn't complain about k
, it complains about smallerList
because you defined smallerlist
(lower-case-l) and then tried to call it with an uppercase-L. Python variables are case-sensitive, ie smallerlist is smallerList == False
.
Looking at your code:
def quickSelect(lines, k):
if len(lines) != 0:
len(lst) != 0
is non-idiomatic; PEP-8 says it should just be lst
, as in if lst:
. Also, camelCase is unPythonic; your function name should be quick_select
. lines
implies you can only operate on text, but your function should work just as well on any orderable data type, so items
would be more accurate. You should have a docstring so the next person to come along has some idea what it does, and we're going to call len(items)
again, so we may as well do it once and store the result. Finally, what if k > len(items)
?
def quick_select(items, k):
"""
Return the k-from-smallest item in items
Assumes 0 <= k < len(items)
"""
num_items = len(items)
if 0 <= k < num_items:
pivot = items[num_items // 2]
continuing:
smallerlist = []
for i in lines:
if i<pivot:
smallerlist.append(i)
largerlist=[]
for i in lines:
if i>pivot:
largerlist.append(i)
You've iterated through lines
twice; you could combine this into a single pass. Also, better variable names:
smaller, larger = [], []
for item in items:
if item < pivot:
smaller.append(item)
elif item > pivot:
larger.append(item)
continuing with better variable names,
num_smaller = len(smaller)
num_pivot = num_items - num_smaller - len(larger)
then your if
s are out of order; they are easier to read in order, so
if k < num_smaller:
return quick_select(smaller, k)
elif k < num_smaller + num_pivot
return pivot
else:
return quick_select(larger, k - num_smaller - num_pivot)
then what if k < 0 or k >= num_items?:
else:
raise ValueError("k={} is out of range".format(k))
Finally, because this function is tail-recursive, it is easy to convert to an iterative function instead:
while True:
pivot = items[num_items // 2]
# ...
if k < num_smaller:
items = smaller
num_items = num_smaller
elif k < num_smaller + num_pivot
return pivot
else:
items = larger
num_items = num_larger
k -= num_smaller + num_pivot
... some assembly required, hope that helps!