2011-12-21 24 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

相关问题