#python #algorithm
#python #алгоритм
Вопрос:
Я изучаю алгоритм быстрого выбора, но мой код не работает.
def qselect(li, k):
if len(li) <= 1:
return li
mid = len(li) // 2
pivot = li[mid]
left, equal, right = [], [], []
for number in li:
if number < pivot:
left.append(number)
elif number > pivot:
right.append(number)
else:
equal.append(number)
if k < len(left):
qselect(left, k)
return left[k-1]
elif k < len(left) len(equal):
return equal[0]
else:
qselect(right, k)
return right[k - len(left) - len(equal)]
li = [2, 36, 5, 21, 8, 13, 11, 20, 5, 4, 1]
k = 8
print(qselect(li,k))
Traceback (most recent call last):
File "q_median.py", line 39, in <module>
print(qselect(li,k))
File "q_median.py", line 30, in qselect
qselect(right, k)
File "q_median.py", line 31, in qselect
return right[k - len(left) - len(equal)]
IndexError: list index out of range
Ошибка «вне индекса», и, насколько я знаю, это означает, что данный индекс больше, чем общая длина списка.
Однако, когда я проверяю длину каждого вложенного списка,
len(left) = 7
len(equal) = 1
len(right) = 3
Итак, я ожидал, что будет напечатано right[0] .
Что не так?
Комментарии:
1. Какого результата вы ожидаете?
2. Я думал, что 8-й элемент, который равен ’13’ из исходного списка, распечатан. @l’L’l
3. Вы определили
k
свой индекс спискаk=8
, так и должно бытьk=7
, поскольку индекс начинается с0
.4. Ну, у меня была такая же мысль, но она по-прежнему возвращает ту же ошибку
5. Взгляните: repl.it/repls/SoulfulTriflingMonitor
Ответ №1:
Что не так, так это то, что вы не проверили заявленные вами длины. Первое, что нужно сделать для отладки, это проверить значения, используемые в строке-нарушителе:
else:
qselect(right, k)
print("right", len(right))
print(k, len(left), len(equal), k - len(left) - len(equal))
return right[k - len(left) - len(equal)]
Вывод:
right 1
8 1 1 6
Traceback (most recent call last):
File "C:UserswdwickarAppDataLocalProgramsPythonPython38ZZZ learningso.py", line 31, in <module>
print(qselect(li,k))
File "C:UserswdwickarAppDataLocalProgramsPythonPython38ZZZ learningso.py", line 24, in qselect
qselect(right, k)
File "C:UserswdwickarAppDataLocalProgramsPythonPython38ZZZ learningso.py", line 27, in qselect
return right[k - len(left) - len(equal)]
IndexError: list index out of range
Обратитесь к этому прекрасному сайту отладки для получения дополнительной помощи.
Комментарии:
1. Спасибо! Я обдумал ваш ответ, но теперь мне интересно, почему len(справа) и len (слева) равны 1. Нужно ли добавлять дополнительные строки для объединения фрагментированного списка? Если да, то почему первое условие, если k < len(слева) работает, когда я ставлю небольшое число?
2. Не размышляйте: отслеживайте выполнение. Найдите конкретную точку отказа, а не просите меня провести общий обзор дизайна.
3. Спасибо! Я наконец-то изменил свой код! Я думаю, вы преподаете мне важный урок. Я ценю!
4. Да, постоянное совершенствование — это долгосрочная цель. Не забудьте каким-то образом удалить вопрос: удалить или принять и ответить (даже если вы сами его пишете). Это дает вам небольшой возврат репутации и позволяет Stack Overflow правильно заархивировать вопрос.