2011-12-21 46 views
22

可能重複:
Check if multiple strings exist in another string如何檢查一行是否有列表中的某個字符串?

我試圖找出是否有一個非常乾淨的方法來測試3個不同的字符串。

基本上我正在使用for循環循環播放一個文件;那麼我必須檢查它是否包含我在列表中設置的3個字符串中的1個。

到目前爲止,我已經找到了多個if條件檢查,但並不覺得真的是優雅和高效:

for line in file 
    if "string1" in line or "string2" in line or "string3" in line: 
     print "found the string" 

我的想法一樣創建一個包含string1string2string3列表,檢查是否有任何這些包含在行中,但似乎沒有我可以比較列表而沒有顯式循環通過列表,在這種情況下,我基本上在多條if語句相同的條件下,我上面寫道。

是否有任何聰明的方法來檢查多個字符串,而無需編寫long if語句或循環通過列表元素?

+0

您是否需要搜索每一行或找到第一行?如果是這樣,你可以通過跳出for循環來進行優化。 – 2011-12-21 00:18:30

回答

56
strings = ("string1", "string2", "string3") 
for line in file: 
    if any(s in line for s in strings): 
     print "yay!" 
+2

儘管['any'](http://docs.python.org/library/functions.html?highlight=any#any)的含義非常合乎邏輯,但我從未使用它,所以我必須查找它。好的代碼@Niklas。 – FakeRainBrigand 2011-12-21 00:13:48

+0

這種行爲幾乎完全相同。 – 2011-12-21 00:15:11

+3

這是一個功能。所有'任何'都是檢查序列中的任何值是否爲真。真正的魔法是爲序列使用生成器表達式。 – 2011-12-21 00:50:43

10

這還是兩個表的笛卡爾積循環,但它確實是一條線:

>>> lines1 = ['soup', 'butter', 'venison'] 
>>> lines2 = ['prune', 'rye', 'turkey'] 
>>> search_strings = ['a', 'b', 'c'] 
>>> any(s in l for l in lines1 for s in search_strings) 
True 
>>> any(s in l for l in lines2 for s in search_strings) 
False 

這還具有以下優勢:any短路,所以循環的停止一旦找到一場比賽。而且,這隻能從search_stringslinesX中找到第一個出現的字符串。如果你想找到多次發生,你可以做這樣的事情:

>>> lines3 = ['corn', 'butter', 'apples'] 
>>> [(s, l) for l in lines3 for s in search_strings if s in l] 
[('c', 'corn'), ('b', 'butter'), ('a', 'apples')] 

如果你覺得編碼更復雜的東西,它似乎阿霍Corasick算法可以在給定的輸入字符串測試多個子的存在。 (感謝Niklas B.指出)我仍然認爲它會導致您的用例二次性能,因爲您仍然必須多次調用它來搜索多行。但是,它會擊敗上述(立方,平均)算法。

+1

其實有。看看Aho-Corasick自動機。它可以在線性時間內完成 – 2014-03-19 17:28:40

+0

@NiklasB。,謝謝,這很有趣!如果我錯了,糾正我,但我認爲結果仍然是二次的,因爲OP想要爲子串匹配測試多行。但是,這仍然擊敗了天真的'任何'版本(立方,假設'in'的平均O(n)性能)。 – senderle 2014-03-19 23:38:10

+0

不,它是線性的。構建自動機是線性時間,並且將線送入自動機的時間也是線性時間 – 2014-03-19 23:39:24

3

一種方法是將搜索字符串組合成一個正則表達式,如this answer

+0

我認爲一個正則表達式更漂亮,但不正則表達式有很多開銷?它可以比簡單的'if ... or ... or':'更有效嗎? – 2017-10-27 09:14:52

+0

@SamRedway有一些開銷,但另一方面,搜索字符串可以組合成一個「一次性」處理的模式。 – 2017-10-27 10:16:07

+0

@SamRedway嗯好吧,快速測試使得正則表達式看起來不好比較 – 2017-10-27 10:36:00

相關問題