2014-12-23 32 views
2

的有效方式我有一个像巨大的字符串:蟒蛇 - 检查字符串的一部分是在列表

睡鼠的故事。曾几何时,有三个小姐姐;他们的名字是Elsie,Lacie和Tillie;和他们住在 的好.... BADWORD底部...

和我有大约400个不好的话列表:

bad_words = ["badword", "badword1", ....] 

什么是检查最有效的方法如果文本包含badwords列表中的坏词?

我可以遍历文本和列表,如:

for word in huge_string: 
    for bw in bad_words_list: 
    if bw in word: 
     # print "bad word is inside text"... 

但这似乎我是从90年代..

更新:不好的话是单个单词。

+3

因此它可以是一个子或实际的话吗?如果单词使用集合。 –

+0

@PadraicCunningham现在的实际单词 – doniyor

+2

您是否尝试过'set intersection'? –

回答

4

车削你的文字变成一组字,并计算它与坏字的交集将会给你摊销速度:

text = "The Dormouse's story. Once upon a time there were three little sisters; and their names were Elsie, Lacie and Tillie; and they lived at the bottom of a well....badword..." 

badwords = set(["badword", "badword1", ....]) 

textwords = set(word for word in text.split()) 
for badword in badwords.intersection(textwords): 
    print("The bad word '{}' was found in the text".format(badword)) 
+0

我喜欢这个解决方案,应该比for循环嵌套'word in text'更有效率。 P.S:你在for循环中忘记了一个'in'。 – LeartS

+0

完美!我需要确切的摊销速度。谢谢 – doniyor

+0

@LeartS:谢谢你的bugreport。现在修好! – inspectorG4dget

2

无需获取文本的所有的话,你可以直接检查,如果一个字符串在另一个字符串,如:

In [1]: 'bad word' in 'do not say bad words!' 
Out[1]: True 

所以,你可以这样做:

for bad_word in bad_words_list: 
    if bad_word in huge_string: 
     print "BAD!!" 
1

这样的:

st = set(s.split()) 

bad_words = ["badword", "badword1"] 
any(bad in st for bad in bad_words) 

或者,如果你想要的话:

st = set(s.split()) 

bad_words = {"badword", "badword1"} 
print(st.intersection(bad_words)) 

如果有像凡句子中结束字badword.badword!然后set方法会失败,你会真正有检查字符串中的每个单词并检查是否有任何坏字与单词或子字符串相同。

st = s.split() 
any(bad in word for word in st for bad in bad_words) 
1

您可以使用any

为了测试是否bad_words是前/后缀:

>>> bad_words = ["badword", "badword1"] 
>>> text ="some text with badwords or not" 
>>> any(i in text for i in bad_words) 
True 
>>> text ="some text with words or not" 
>>> any(i in text for i in bad_words) 
False 

它会比较任何bad_words'项目都在text,用 “子”。

为了测试准确匹配:

>>> text ="some text with badwords or not" 
>>> any(i in text.split() for i in bad_words) 
False 
>>> text ="some text with badword or not" 
>>> any(i in text.split() for i in bad_words) 
True 

它会比较任何bad_words'项目都在text.split(),也就是说,如果它是一个确切的项目。

1

s是长字符串。使用&运算符或set.intersection方法。

In [123]: set(s.split()) & set(bad_words) 
Out[123]: {'badword'} 

In [124]: bool(set(s.split()) & set(bad_words)) 
Out[124]: True 

甚至更好使用set.isdisjoint。 一旦找到匹配项,就会短路。

In [127]: bad_words = set(bad_words) 

In [128]: not bad_words.isdisjoint(s.split()) 
Out[128]: True 

In [129]: not bad_words.isdisjoint('for bar spam'.split()) 
Out[129]: False 
-1
s = " a string with bad word" 
text = s.split() 

if any(bad_word in text for bad_word in ('bad', 'bad2')): 
     print "bad word found" 
+0

那只会打印最后一个bad_word?如果列表中元素的“任何”都是真的(任何),任何只是返回true或false, –

1

上的所有优秀的答案的上方,for now, whole words条款在您的评论点在正则表达式的方向。

你可能想建立一个组合表达式像bad|otherbad|yetanother

r = re.compile("|".join(badwords)) 
r.search(text) 
0

我会用一个filter功能:

filter(lambda s : s in bad_words_list, huge_string.split()) 
相关问题