Python list.index выдает исключение, если индекс не найден
Почему list.index генерирует исключение вместо использования произвольного значения (например, -1
)? Какова идея этого?
Для меня это выглядит более чистым, чтобы иметь дело со специальными значениями, а не с исключениями.
EDIT: я не понял, что -1
- потенциально допустимое значение. Тем не менее, почему не что-то еще? Как насчет значения None?
Ответы
Ответ 1
Потому что -1
сам по себе является допустимым индексом. Он мог бы использовать другое значение, например None
, но это не было бы полезно, что -1
может быть в других ситуациях (таким образом, str.find()
), и будет просто проверять ошибки, что и есть то, что исключения для.
Ответ 2
Чтобы добавить к ответу Девина: это старая дискуссия между специальными значениями возврата и исключениями. Многие гуру по программированию предпочитают исключение, потому что при исключении я могу увидеть всю стеклу и немедленно указать, что не так.
Ответ 3
Ну, специальное значение действительно должно быть None
, потому что -1 является допустимым индексом (что означает последний элемент списка).
Вы можете эмулировать это поведение:
idx = l.index(x) if x in l else None
Ответ 4
Обсуждение "исключение-vs-error value" частично связано с ясностью кода. Рассмотрим код со значением ошибки:
idx = sequence.index(x)
if idx == ERROR:
# do error processing
else:
print '%s occurred at position %s.' % (x, idx)
Обработка ошибок заканчивается заполненной в середине нашего алгоритма, затеняя поток программы. С другой стороны:
try:
idx = sequence.index(x)
print '%s occurred at position %s.' % (x, idx)
except IndexError:
# do error processing
В этом случае количество кода фактически одинаково, но основной алгоритм не прерывается обработкой ошибок.
Ответ 5
В Python -1 является допустимым индексом, означающим число из конца списка (вместо начала), поэтому, если вы должны были сделать
idx = mylist.index(someval)
nextval = mylist[idx+1]
тогда вы получите первое значение массива, вместо того чтобы понять, что произошла ошибка. Таким образом вы можете поймать исключение и справиться с ним. Если вы не хотите исключений, просто проверьте заранее:
if someval in mylist:
idx = mylist.index(someval)
Изменить: на самом деле нет никакой точки в возврате None, потому что если вы собираетесь тестировать None, вы можете также проверить, находится ли значение в списке, как указано выше!
Ответ 6
В основном это означает, что ошибки будут обнаружены как можно скорее. Например, рассмотрим следующее:
l = [1, 2, 3]
x = l.index("foo") #normally, this will raise an error
l[x] #However, if line 2 returned None, it would error here
Вы заметите, что ошибка будет сброшена в l[x]
, а не в x = l.index("foo")
, если индекс должен был вернуть None. В этом примере это не очень важно. Но представьте себе, что третья строка находится в каком-то совершенно другом месте в программе с миллионами строк. Это может привести к некоторому кошмару отладки.
Ответ 7
Я согласен с Devin Jeanpierre и добавлю, что обработка особых значений может показаться хорошей в небольших примерах, но (с несколькими заметными исключениями, например NaN в FPU и Null в SQL), она не масштабируется почти так же хорошо. Единственный раз, когда он работает, - где:
- Обычно у вас много вложенной однородной обработки (например, математика или SQL).
- Вам не нужно различать типы ошибок
- Вам все равно, где произошла ошибка.
- Операции - это чистые функции без побочных эффектов.
- Отказ может дать разумный смысл на более высоком уровне (например, "Нет совпадающих строк" )
Ответ 8
Одна простая идея: -1
отлично используется как индекс (как и другие отрицательные значения).
Ответ 9
Это семантический аргумент. Если вы хотите узнать индекс элемента, вы утверждаете, что он уже существует в списке. Если вы хотите узнать, существует ли он, вы должны использовать in
.
Ответ 10
def GetListIndex(list, searchString):
try:
return list.index(searchString)
except ValueError:
return False
except Exception:
raise