如何检查一行是不是有列表中的一个字符串? [复制]
Posted
技术标签:
【中文标题】如何检查一行是不是有列表中的一个字符串? [复制]【英文标题】:How to check if a line has one of the strings in a list? [duplicate]如何检查一行是否有列表中的一个字符串? [复制] 【发布时间】:2012-01-24 21:34:04 【问题描述】:可能重复: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"
我想创建一个包含 string1
、string2
和 string3
的列表,并检查其中是否包含其中任何一个,但似乎我不能只比较列表而不显式循环遍历列表,在这种情况下,我基本上处于与上面编写的多重 if 语句相同的条件。
有没有什么聪明的方法可以检查多个字符串,而无需编写长 if 语句或循环遍历列表的元素?
【问题讨论】:
你需要搜索每一行还是只找到第一行?如果是这样,您可以通过跳出 for 循环进行优化。 【参考方案1】:strings = ("string1", "string2", "string3")
for line in file:
if any(s in line for s in strings):
print "yay!"
【讨论】:
虽然any
的含义很合乎逻辑,但我从未使用过它,所以我不得不查一下。不错的代码@Niklas。
这几乎完全相同。
这是一个函数。所有any
所做的只是检查序列中的任何值是否为真。真正的魔力是为序列使用生成器表达式。
@Niklas B.:很抱歉评论晚了,但是有没有办法打印找到的字符串?你会怎么做。谢谢。
@Pitto:啊,我现在才看到您的评论是对 Shabkar 的回应 :) 但是,line
不是找到的字符串。那将是 string
的匹配元素【参考方案2】:
这仍然循环通过两个列表的笛卡尔积,但它只做一行:
>>> 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
短路的优点,因此一旦找到匹配项,循环就会停止。此外,这只会在linesX
中找到来自search_strings
的字符串的第一次出现。如果您想查找多个匹配项,您可以执行以下操作:
>>> 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')]
如果您想编写更复杂的代码,Aho-Corasick 算法似乎可以测试给定输入字符串中是否存在多个子字符串。 (感谢 Niklas B. 指出这一点。)我仍然认为它会为您的用例带来二次性能,因为您仍然需要多次调用它来搜索多行。但是,它会击败上述(三次,平均)算法。
【讨论】:
其实有。查看 Aho-Corasick 自动机。它可以在线性时间内完成 @NiklasB.,谢谢,这很有趣!如果我错了,请纠正我,但我认为结果仍然是二次的,因为 OP 想要测试多行的子字符串匹配。但这仍然胜过幼稚的any
版本(三次,假设平均 O(n) 性能为 in
)。
不,它是线性的。构建自动机是线性时间,将字符串输入自动机也是线性时间
或者更准确地说,你用针构建了一次自动机,然后在每一行重复使用它
我以为自动机是用针做的……【参考方案3】:
一种方法是将搜索字符串组合成一个正则表达式模式,如this answer。
【讨论】:
我认为正则表达式更漂亮,但正则表达式不是有很多开销吗?它真的比简单的'if ... or ... or ...:'更有效吗? @SamRedway 有一些开销,但另一方面,搜索字符串可以组合成一个“一次性”处理的模式。 @SamRedway 嗯,好的,快速测试使正则表达式看起来很糟糕 所以我猜想在大多数用例中,可读性比效率更重要,这是基于该指标的完全合理的方法。会说“更有效”可能会产生误导。 @SamRedway 是的,现在编辑了。以上是关于如何检查一行是不是有列表中的一个字符串? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何进行`if`检查键入的单词是不是等于C中字符串列表中的某个单词? [复制]
R - 对于数据框中的每一行,如何检查是不是至少有一列不是 NA? [复制]
如何使用条件检查列表中是不是存在字符串类型的输入? [复制]