2010-01-31 26 views
20

Dla list metoda list.index(x) zwraca indeks na liście pierwszego elementu, którego wartością jest x. Ale jeśli chcę zajrzeć do elementów listy, a nie tylko do wszystkich elementów, w jaki sposób mogę uzyskać najbardziej odpowiednią metodę Pythoninc?Zdobądź pierwszy indeks listy zawierający podtytuły?

Na przykład,

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

funkcja powróci 1 wyposażoną w argument tiger.

Odpowiedz

23

Non-slicky Metoda:

def index_containing_substring(the_list, substring): 
    for i, s in enumerate(the_list): 
     if substring in s: 
       return i 
    return -1 
+0

Lepiej niż moje powiedziałbym. + 1 ~ –

2
def find(l, s): 
    for i in range(len(l)): 
     if l[i].find(s)!=-1: 
      return i 
    return None # Or -1 
2

Jest bardzo śliska i bardzo wydajny.

>>> 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 

Jedyny problem polega na tym, że spowoduje to zatrzymanie zatrzymania, jeśli przedmiot nie zostanie znaleziony (choć można go łatwo usunąć).

+1

StopIteracja może być uniknięta: 'return next ((dla i, j dla wyliczenia (lst) jeśli predykat (j)), -1)' (Python 2.6+) – vsvasya

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

Uwaga: Spowoduje to podniesienie ValueError w przypadku nie znaleziono, co jest lepsze moim zdaniem.

+0

Wyobraźnia, ale nie jest wydajna, ponieważ testuje wszystkie elementy listy, niezależnie od tego, czy tekst został znaleziony wcześniej, czy nie. Ponadto, funkcja "something'.find (s) Pythona zwraca -1, gdy nie znaleziono żadnego dopasowania, więc nazwałbym to Pythonicznym. –

+0

Nie działa, przynajmniej w Pythonie 2.6. W 'min()' nie można używać argumentów iteracyjnych i dodatkowych. @Etiene: to wyrażenie generujące, a nie rozumienie listy, więc nie generuje wszystkiego. –

+0

@ Etienne - przedwczesna optymalizacja jest źródłem wszelkiego zła itp. @Max - jesteś poprawny, naprawiony. – abyx

3

Variation roztworu abyx (zoptymalizowane do zatrzymania, gdy zostanie znaleziony)

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

Jeśli są wstępnie 2,6 musisz umieścić next() na koniec

def first_substring(strings, substring): 
    return (i for i, string in enumerate(strings) if substring in string).next() 
1
>>> 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 
2

Możesz użyć jednej z następujących linii:

index = [idx for idx, s in enumerate(l) if 'tiger' in s][0] 
Powiązane problemy