список.функция index() для Python, которая не создает исключения, когда ничего не найдено



в Python list.index(x) выдает исключение, если элемент не существует. Есть ли лучший способ сделать это, который не требует обработки исключений?

552   9  

9 ответов:

Если вам все равно, где находится соответствующий элемент, то используйте:

found = x in somelist

Если вы заботитесь, то используйте LBYL стиль условное выражение:

i = somelist.index(x) if x in somelist else None

реализовать свой собственный индекс для списка?

class mylist(list):
  def index_withoutexception(self,i):
    try:
        return self.index(i)
    except:
        return -1

таким образом, вы можете использовать список, и с вашим index2, вернуть то, что вы хотите в случае ошибки.

Вы можете использовать его как это:

  l = mylist([1,2,3,4,5]) # This is the only difference with a real list
  l.append(4) # l is a list.
  l.index_withoutexception(19) # return -1 or what you want

написать функцию, которая делает то, что вам нужно:

def find_in_iterable(x, iterable):
    for i, item in enumerate(iterable):
        if item == x:
            return i
    return None

Если вам нужно только знать, существует ли элемент, но не Индекс, вы можете использовать in:

x in yourlist

Да, есть. Вы можете например. сделать что-то похожее на это:

test = lambda l, e: l.index(e) if e in l else None

, которая работает так:

>>> a = ['a', 'b', 'c', 'g', 'c']
>>> test(a, 'b')
1
>>> test(a, 'c')
2
>>> test(a, 't')
None

Итак, test()возвращает индекс элемента (второй параметр) в заданном списке (первый параметр), , если он не был найден (в этом случае он будет возвращать None, но это может быть все, что вы найдете подходящий).

Если вам все равно, где он находится в последовательности, только его присутствие, то используйте in оператора. В противном случае напишите функцию, которая выполняет рефакторинг обработки исключений.

def inlist(needle, haystack):
  try:
    return haystack.index(needle)
  except ...:
    return -1

надеюсь, что это помогает

lst= ','.join('qwerty').split(',') # create list
i='a'  #srch string
lst.index(i) if i in lst else None

мне нравится использовать Web2py этосписок класс, найденный в модуле хранения своего пакета глюона. Модуль хранения предлагает структуры данных типа списка (List) и словаря (Storage), которые не вызывают ошибок, когда элемент не найден.

скачать источник web2py, затем скопируйте-вставьте папку пакета gluon в сайт-пакеты вашей установки python.

теперь попробуйте:

>>> from gluon.storage import List
>>> L = List(['a','b','c'])
>>> print L(2)
c
>>> print L(3) #No IndexError!
None

обратите внимание, он может также ведите себя как обычный список:

>>> print L[3]

Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
l[3]
IndexError: list index out of range

TL;DR: исключения-это ваш друг, и лучший подход к вопросу, как указано.

OP пояснил в комментарии, что для их случая использования на самом деле не было важно знать, что такое индекс. Как отмечает принятый ответ, используя x in somelist Это лучший ответ, если вам все равно.

но я предполагаю, как и предполагает исходный вопрос, что вы do забота, что индекс. В этом случае я отмечу, что все остальные решения требуется сканирование списка дважды, что может привести к большому снижению производительности.

кроме того, как писал в комментарии достопочтенный Раймонд Хеттингер

даже если бы у нас был список.найти, что вернулся -1 вам все равно нужно будет проверить, чтобы увидеть, если i == -1 и принять некоторые меры.

поэтому я буду отталкиваться от предположения в исходном вопросе, что исключений следует избегать. Я предлагаю, чтобы исключения были вашим другом. Они ничего не будут боюсь, они не являются неэффективными, и на самом деле вы должны быть знакомы с ними, чтобы написать хороший код.

поэтому я думаю, что лучший ответ-просто использовать подход try-except:

try: i = somelist.index(x) except ValueError: # deal with it

"разберись с этим " просто означает, что вам нужно сделать: установить i в значение sentinel, создать собственное исключение, следовать другой ветке кода и т. д.

нет встроенный способ сделать то, что вы хотите сделать.

вот хороший пост, который может помочь вам: почему в списке нет безопасного метода "get", такого как словарь?

Comments

    Ничего не найдено.