Получить первый индекс списка, содержащий подстроку? - PullRequest
29 голосов
/ 31 января 2010

Для списков метод list.index(x) возвращает индекс в списке первого элемента со значением x. Но если я хочу заглянуть в элементы списка, а не только в элементы целиком, как мне сделать для этого максимально возможный метод Pythoninc?

Например, с

l = ['the cat ate the mouse',
     'the tiger ate the chicken',
     'the horse ate the straw']

эта функция вернет 1 с аргументом tiger.

Ответы [ 8 ]

32 голосов
/ 31 января 2010

Не скользкий метод:

def index_containing_substring(the_list, substring):
    for i, s in enumerate(the_list):
        if substring in s:
              return i
    return -1
5 голосов
/ 11 июля 2016

с однострочником:

index = [idx for idx, s in enumerate(l) if 'tiger' in s][0]
3 голосов
/ 31 января 2010

Вариация решения Abyx (оптимизировано для остановки, когда совпадение найдено)

def first_substring(strings, substring):
    return next(i for i, string in enumerate(strings) if substring in string)

Если вы до 2.6, вам нужно поставить next() в конце

def first_substring(strings, substring):
    return (i for i, string in enumerate(strings) if substring in string).next()
2 голосов
/ 31 января 2010

Это довольно гладко и довольно эффективно.

>>> def find(lst, predicate):
...     return (i for i, j in enumerate(lst) if predicate(j)).next()
... 
>>> l = ['the cat ate the mouse','the tiger ate the chicken','the horse ate the straw']
>>> find(l, lambda x: 'tiger' in x)
1

Единственная проблема заключается в том, что он вызывает StopIteration, если элемент не найден (хотя это легко исправить).

2 голосов
/ 31 января 2010
def find(l, s):
    for i in range(len(l)):
        if l[i].find(s)!=-1:
            return i
    return None # Or -1
1 голос
/ 26 марта 2018

imho с этой строкой вы найдете только первый случай без обработки всего списка

index = next((i for i in enumerate(l) if "tiger" in i[1]),[-1,-1])[0]

1 голос
/ 24 апреля 2013
  >>> li = ['my','array','with','words']
  >>> reduce(lambda tup, word: (tup[0], True) if not tup[1] and word  == 'my' else (tup[0]+1 if not tup[1] else tup[0], tup[1]), li, (0, False))[0]
  0
  >>> reduce(lambda tup, word: (tup[0], True) if not tup[1] and word  == 'words' else (tup[0]+1 if not tup[1] else tup[0], tup[1]), li, (0, False))[0]
  3
1 голос
/ 31 января 2010
def first_substring(strings, substring):
    return min(i for i, string in enumerate(strings) if substring in string)

Примечание: это повысит ValueError в случае, если совпадение не найдено, что лучше, на мой взгляд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...