У меня есть кодекс, который выглядит примерно так:
thing_index = thing_list.index(thing)
otherfunction(thing_list, thing_index)
хорошо, таким образом, это упрощено, но Вы получаете идею. Теперь thing
не мог бы на самом деле быть в списке, в этом случае я хочу пройти-1 как thing_index
. На других языках это - то, что Вы ожидали бы index()
возвратиться, если это не могло бы найти элемент. На самом деле это бросает a ValueError
.
Я мог сделать это:
try:
thing_index = thing_list.index(thing)
except ValueError:
thing_index = -1
otherfunction(thing_list, thing_index)
Но это чувствует себя грязным, плюс я не знаю если ValueError
мог быть поднят по некоторой другой причине. Я предложил следующее решение на основе функций генератора, но это кажется небольшим комплексом:
thing_index = ( [(i for i in xrange(len(thing_list)) if thing_list[i]==thing)] or [-1] )[0]
Есть ли более чистый способ достигнуть того же самого? Давайте предположим, что список не сортирован.
Эта проблема является одной из языковой философии. Например, в Java всегда была традиция, что исключения действительно должны использоваться только в «исключительных обстоятельствах», которые происходят, когда произошло ошибки, а не для контроля потока . Вначале это было для показателей эффективности, поскольку исключения Java были медленными, но теперь это стало принятым стилем.
В отличие от Python всегда использовали исключения, чтобы указать нормальный поток программы, как повышение ValueError
, как мы обсуждаем здесь. В стиле Python нет ничего "грязного" в стиле Python, и там еще много, где это произошло. Еще более распространенным примером является замедленность
, который поднимается методом ITERATOR
.
В этом документе он буквально называется вопросительным знаком « (включена в дефис) ( http://www.ietf.org/rfc/rfc2396.txt - Прокрутите до 3,2 полномочия компонента).
Я согласен, это плохое имя. Хеш (#) называется идентификатором фрагмента (прокрутите вниз до 4.1). Так что, возможно, его следует назвать идентификатором запроса ».
-121--1728972-thing_index = thing_list.index(elem) if elem in thing_list else -1
одна строка. Простой. Без исключений.
Нет ничего плохого в вашем коде, который использует ValueError
. Вот еще один одноклассник, если вы хотите избежать исключений:
thing_index = next((i for i, x in enumerate(thing_list) if x == thing), -1)
Нет ничего «грязного» с использованием предложения TRY-BELE. Это питон путь. ValueError
будет поднят только методом .index
.index .] Поскольку это единственный код, который у вас там!
Чтобы ответить на комментарий:
В Python проще просить прощения, чем получить разрешение Философия хорошо создана, а NO index
не будет поднимать этот тип ошибки для любых других вопросов. Не то чтобы я мог подумать.
Тип dict
имеет функцию get
, где если ключ не существует в словаре, то 2-й аргумент к get
- это значение, которое он должен вернуть. Аналогично существует setdefault
, который возвращает значение в dict
, если ключ существует, в противном случае он устанавливает значение в соответствии с вашим параметром по умолчанию, а затем возвращает ваш параметр по умолчанию.
Вы можете расширить тип list
, чтобы использовать метод getindexdefault
.
class SuperDuperList(list):
def getindexdefault(self, elem, default):
try:
thing_index = self.index(elem)
return thing_index
except ValueError:
return default
Который затем можно было бы использовать как:
mylist = SuperDuperList([0,1,2])
index = mylist.getindexdefault( 'asdf', -1 )
Как насчет этого:
otherfunction(thing_collection, thing)
, а не разоблачить что-то, что зависит от реализации, как индекс списка в интерфейсе функций, передайте коллекцию и то, что другие, и пусть другие проблемы с вопросами «Тест на членство». Если прочесть записывается, чтобы быть коллекцией - тип агностики, то, вероятно, начнутся с:
if thing in thing_collection:
... proceed with operation on thing
, который будет работать, если Thing_Collection - это список, кортеж, набор или Dict.
Это, возможно, более четко, чем:
if thing_index != MAGIC_VALUE_INDICATING_NOT_A_MEMBER:
, который является кодом, который вы уже имеете в другой.
Я не знаю, почему вы должны думать, что это грязно ... из-за исключения? Если вы хотите, чтобы онеленер, вот оно:
thing_index = thing_list.index(elem) if thing_list.count(elem) else -1
, но я бы посоветовал против этого; Я думаю, что решение ROSS ROGERS является лучшим, используйте объект для инкапсуляции вашего поведения Desiderd, не пытайся отталкивать язык на его ограничения на стоимость читабельности.