2010-01-31 69 views
20

對於列表,方法list.index(x)返回值爲x的第一項的列表中的索引。但是如果我想查看列表項目,而不僅僅是整個項目,我如何爲此做出最Pythoninc方法?獲取第一個包含子字符串的索引?

例如,

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

這個函數將返回提供參數tiger1

回答

23

非slicky方法:

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

我會說我比我的滑。 + 1〜 – 2010-01-31 07:31:32

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

這是相當光滑和相當有效。

>>> 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異常,如果該項目沒有找到(雖然這很容易補救)。

+1

StopIteration可以避免: 'return next((if for i,j in enumerate(lst)if predicate(j)),-1)' (Python 2.6+) – vsvasya 2012-03-19 20:23:01

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

注意:這將提高ValueError的情況下,沒有找到匹配的,這在我看來是更好的。

+0

花式但不高效,因爲它測試列表中的所有元素,而不管文本是否先前被找到。 另外,Python的'something'.find(s)函數在找不到匹配項時返回-1,所以我會調用Pythonic。 – 2010-01-31 07:38:35

+0

不起作用,至少在Python 2.6中。你不能在'min()'中同時使用迭代和額外的參數。 @Etiene:這是一個生成器表達式,不是列表理解,所以它不會生成所有內容。 – 2010-01-31 07:40:43

+0

@Etienne - 不成熟的優化是一切邪惡的根源等等。 @Max - 你是對的,固定的。 – abyx 2010-01-31 07:46:24

3

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

您可以使用以下一行代碼:

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