2010-01-31 13 views
20

Bei Listen gibt die Methode list.index(x) den Index in der Liste des ersten Elements mit dem Wert x zurück. Aber wenn ich in die Listenelemente schauen möchte, und nicht nur auf die ganzen Elemente, wie mache ich die meiste Pythoninc-Methode dafür?Erhalte ersten Listenindex mit Sub-String?

Zum Beispiel mit

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

diese Funktion zurückkehren würde 1 mit dem Argument versehen tiger.

Antwort

23

Eine nicht slicky Methode:

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

Slicker als meins würde ich sagen. + 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

Das ist ziemlich glatt und ziemlich effizient.

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

Das einzige Problem ist, dass es StopIteration erhöhen wird, wenn das Element nicht gefunden wird (obwohl das leicht behoben ist).

+1

StopIteration kann vermieden werden: 'return next ((i für i, j in enumerate (lst) wenn Prädikat (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) 

Hinweis: Diese ValueError im Fall erhöhen wird keine Übereinstimmung gefunden wird, die meiner Meinung nach besser ist.

+0

Fancy aber nicht effizient, wie es testet alle Elemente der Liste unabhängig davon, ob der Text zuvor gefunden wurde oder nicht. Auch Pythons 'something.find (s) -Funktion gibt -1 zurück, wenn keine Übereinstimmung gefunden wird, also würde ich das Pythonic nennen. –

+0

Funktioniert nicht, zumindest in Python 2.6. Sie können nicht ein iterables und ein extra Argument in 'min()' verwenden. @Etiene: Das ist ein Generatorausdruck, kein Listenverständnis, also würde es nicht alles erzeugen. –

+0

@Etienne - vorzeitige Optimierung ist die Wurzel aller Übel usw. @Max - Sie sind richtig, behoben. – abyx

3

Variation von abyx Lösung (optimiert zu stoppen, wenn die Übereinstimmung gefunden wird)

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

Wenn Sie bereits sind 2.6 Sie werden die next() am Ende

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
setzen müssen

Sie können den folgenden Einzeiler verwenden:

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