2012-03-08 102 views
6

任何字符串列表中我有一個字符串列表,從中我要找到每一個具有行的「http://」在裏面,但沒有「lulz」,「 LMFAO「」巴紐」,或在它的字符串列表其他任何物品。我會怎麼做呢?如果字符串不包含在python

我的直覺告訴我,使用正則表達式,但我有道義上的反對巫術。

回答

10

這裏是一個還算可擴展的,如果字符串排除列表是大的選項:

exclude = ['lulz', 'lmfao', '.png'] 
filter_func = lambda s: 'http://' in s and not any(x in s for x in exclude) 

matching_lines = filter(filter_func, string_list) 

列表理解的選擇:

matching_lines = [line for line in string_list if filter_func(line)] 
+0

太棒了!我開始使用lambda!我知道它存在是有原因的! – directedition 2012-03-08 01:23:12

+1

你不需要。 'lambda'允許你定義內聯函數,而不是設置一個變量'filter_func';但是你可以很容易地編寫'高清filter_func(S):返回的「http://」在S和沒有任何(X在S代表X中排除)'。請記住,函數是對象。 – 2012-03-08 02:46:13

+0

我甚至會說這是對'lambda'的不當使用。在這裏沒有理由選擇「def」。 – wim 2012-03-08 03:42:38

2

試試這個:

for s in strings: 
    if 'http://' in s and not 'lulz' in s and not 'lmfao' in s and not '.png' in s: 
     # found it 
     pass 

其他選項,如果你需要你的選擇更加靈活:

words = ('lmfao', '.png', 'lulz') 
for s in strings: 
    if 'http://' in s and all(map(lambda x, y: x not in y, words, list(s * len(words))): 
     # found it 
     pass 
+0

這是我的第一個方法。但隨着我的長大名單和行變得笨拙,我希望有一個更好的辦法。 – directedition 2012-03-08 01:06:09

+1

這可能失控,如果他想延長停止詞列表。你會如何改變你的方法?但是,對於簡單的解決方案,還是+1 – prelic 2012-03-08 01:06:18

3

這幾乎等同於FJ的解決方案,但使用generator expressions代替lambda表達式和過濾功能:

haystack = ['http://blah', 'http://lulz', 'blah blah', 'http://lmfao'] 
exclude = ['lulz', 'lmfao', '.png'] 

http_strings = (s for s in haystack if s.startswith('http://')) 
result_strings = (s for s in http_strings if not any(e in s for e in exclude)) 

print list(result_strings) 

當我運行這個它打印:

['http://blah'] 
+0

發電機+1。但是,請注意,您可以將其作爲(幾乎)單行程:'result_strings = [s for s in haystack if s.startswith('http://')and any any(in in for in in exclude )]'。它需要一個換行符合80列(按照大多數風格指南),但我認爲它比雙發生器版本稍微容易一些。 timeit還報告說,這比FJ的過濾器版本(IMO,這是三者中最難遵循的版本)稍微快一點,並且也稍微快一些。 – lvc 2012-03-08 01:43:37