У меня есть код, который выглядит примерно так:
thing_index = thing_list.index(thing)
otherfunction(thing_list, thing_index)
хорошо, это упрощено, но вы поняли идею. Теперь thing
может не быть в списке, и в этом случае я хочу передать -1 как thing_index
. На других языках это то, что вы ожидаете index()
вернуть, если он не может найти элемент. Фактически он выбрасывает 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]
Есть ли более чистый способ добиться того же? Предположим, список не отсортирован.
thing_index
." - Это определенно непифонично. Передача (бессмысленного) значения токена в случае, если операция не удалась, не одобряется - исключения действительно здесь правильный путь. Тем более,thing_list[-1]
что это допустимое выражение, означающее последнюю запись в списке.str.find
метод, который делает именно это: возвращается,-1
когда игла не найдена в теме.str.index()
генерирует исключение, если строка поиска не найдена.Ответы:
В использовании предложения try-except нет ничего «грязного». Это питонический путь.
ValueError
будет вызван только.index
методом, потому что это единственный код, который у вас есть!Чтобы ответить на комментарий:
в Python легче просить прощения, чем получать разрешение, философия хорошо известна, и нет
index
не вызовет этот тип ошибки для каких-либо других проблем. Не то чтобы я мог думать ни о чем.источник
{}.get(index, '')
более питонический? Не говоря уже о том, что короче читабельнее.None
вместо -1 было бы нормально, но, как вы сами прокомментировали, str.find () возвращает -1, так почему не должно быть list.find (), который делает то же самое? Я неotherfunction
. С другой стороны, если он не сломан, ...Одна линия. Просто. Без исключений.
источник
for
.indexOf = lambda item,list_ : list_.index(item) if item in list_ else -1 # OR None
dict
Типа имеетget
функцию , где , если ключ не существует в словаре, второй аргументget
этого значения , которое он должен вернуться. Точно так же естьsetdefault
, который возвращает значение в,dict
если ключ существует, в противном случае он устанавливает значение в соответствии с вашим параметром по умолчанию, а затем возвращает ваш параметр по умолчанию.Вы можете расширить
list
тип, чтобы получитьgetindexdefault
метод.Что затем можно было бы использовать как:
источник
Нет ничего плохого в вашем коде, который использует
ValueError
. Вот еще один однострочник, если вы не хотите исключений:источник
next()
функция существует в Python 2.6+. Но это легко реализовать для 2.5, см. Реализацию функции next () для Python 2.5Это вопрос философии языка. В Java, например, всегда существовала традиция, согласно которой исключения действительно должны использоваться только в «исключительных обстоятельствах», то есть когда произошли ошибки, а не для управления потоком . Вначале это было из соображений производительности, поскольку исключения Java выполнялись медленно, но теперь это стало общепринятым стилем.
Напротив, Python всегда использовал исключения для обозначения нормального выполнения программы, например, поднимая a,
ValueError
как мы здесь обсуждаем. В стиле Python нет ничего «грязного», и есть еще много всего, откуда это взялось. Еще более распространенный пример -StopIteration
исключение, которое вызывается методом итератора,next()
чтобы сигнализировать об отсутствии других значений.источник
StopIteration
потому что ясно определено, что означает исключение.ValueError
просто слишком общий.Если вы делаете это часто, лучше использовать вспомогательную функцию:
источник
А как насчет этого 😃:
источник
Как насчет этого:
Вместо того, чтобы открывать что-то настолько зависящее от реализации, как индекс списка в интерфейсе функции, передайте коллекцию и объект и позвольте другой функции заниматься проблемами «проверки принадлежности». Если другая функция написана как независимая от типа коллекции, она, вероятно, будет начинаться с:
который будет работать, если thing_collection является списком, кортежем, набором или dict.
Возможно, это яснее, чем:
это код, который у вас уже есть в другой функции.
источник
А как насчет этого:
источник
У меня такая же проблема с методом ".index ()" в списках. У меня нет проблем с тем, что это вызывает исключение, но я категорически не согласен с тем фактом, что это не описательная ValueError. Я мог понять, если бы это была ошибка IndexError.
Я понимаю, почему возврат «-1» тоже будет проблемой, потому что это действительный индекс в Python. Но на самом деле я никогда не ожидаю, что метод ".index ()" вернет отрицательное число.
Вот один лайнер (хорошо, это довольно длинная строка ...), проходит по списку ровно один раз и возвращает «Нет», если элемент не найден. Было бы тривиально переписать его так, чтобы он возвращал -1, если вы того пожелаете.
Как пользоваться:
источник
Я не знаю, почему вы должны думать, что он грязный ... из-за исключения? Если вам нужен одинарный лайнер, вот он:
но я бы посоветовал не использовать его; Я думаю, что решение Росс Роджерс является лучшим, используйте объект для инкапсуляции вашего желаемого поведения, не пытайтесь довести язык до предела за счет удобочитаемости.
источник
find()
функцию, и все будет чисто;)Я бы предложил:
источник