在python中检查字符串的子字符串是否在字符串列表中
我有一本食品词典:在python中检查字符串的子字符串是否在字符串列表中,python,string,list,dictionary,nlp,Python,String,List,Dictionary,Nlp,我有一本食品词典: foods={ "chicken masala" : "curry", "chicken burger" : "burger", "beef burger" : "burger", "chicken soup" : "appetizer", "vegetable" : "curry" } 现在我有一个字符串列表: queries = ["best burger", "something else"] 我必须找出查询中是否有任何字符串在我们的食品词典中包
foods={
"chicken masala" : "curry",
"chicken burger" : "burger",
"beef burger" : "burger",
"chicken soup" : "appetizer",
"vegetable" : "curry"
}
现在我有一个字符串列表:
queries = ["best burger", "something else"]
我必须找出查询中是否有任何字符串在我们的食品
词典中包含和条目。
与上面的示例一样,对于最佳汉堡
,它应该返回True。
目前,我正在为foods.keys()
中的所有条目计算列表中每个字符串之间的余弦相似性。
它可以工作,但时间效率很低。食品
词典有近1000条词条。有没有什么有效的方法
编辑:
这里最好的汉堡应该被退回,因为里面有汉堡
,而且汉堡
也存在于鸡肉汉堡
中的foods.keys()
。我基本上是想找出是否有任何关于食物类型的疑问
我是这样计算的:
import re, math
from collections import Counter
WORD = re.compile(r'\w+')
def get_cosine(text1, text2):
vec1 = text_to_vector(text1.lower())
vec2 = text_to_vector(text2.lower())
intersection = set(vec1.keys()) & set(vec2.keys())
numerator = sum([vec1[x] * vec2[x] for x in intersection])
sum1 = sum([vec1[x]**2 for x in vec1.keys()])
sum2 = sum([vec2[x]**2 for x in vec2.keys()])
denominator = math.sqrt(sum1) * math.sqrt(sum2)
if not denominator:
return 0.0
else:
return (float(numerator) / denominator) * 100
foods={
"chicken masala" : "curry",
"chicken burger" : "burger",
"beef burger" : "burger",
"chicken soup" : "appetizer",
"vegetable" : "curry"
}
queries = ["best burger", "something else"]
flag = False
food = []
for phrase in queries:
for k in foods.keys():
cosine = get_cosine(phrase, k)
if int(cosine) > 40:
flag = True
food.append(phrase)
break
print('Foods:', food)
输出:
Foods: ['best burger']
解决方案:
尽管@Black Thunder的解决方案适用于我在示例中提供的示例,但它不适用于像
最佳汉堡
这样的查询。但这种解决方案在这种情况下有效。这是我最关心的问题。谢谢@Andrej Kesely。这就是我在解中选择余弦相似性的原因。但我认为SequenceMatcher在这里工作得更好 如果您想要查询和键之间的匹配列表,可以使用列表理解:
matches=[food for food in querys if food in foods]
您可以做这样简单的事情
首先拿到所有的钥匙
data = foods.keys()
现在将字符串列表转换为一个逗号分隔的字符串。这将更容易检查子字符串匹配
queries = ','.join(queries)
现在检查子字符串匹配
for food in data:
food = food.split()
for item in food:
if item in data:
print True
请尝试以下代码:
queries = ["best burger", "order"]
foods={
"chicken masala" : "curry",
"chicken burger" : "burger",
"beef burger" : "burger",
"chicken soup" : "appetizer",
"vegetable" : "curry"
}
output = []
for y in queries: #looping through the queries
for x in y.split(" "): #spliting the data in the queries for matches
for z in foods: #taking the keys (same as foods.keys)
if x in z: #Checking if the data in queries matches any data in the keys
output.append(z) #if matches, appending the data
print(output)
输出:
['chicken burger', 'beef burger']
您可以使用
difflib
()查找相似之处(可能需要对系数进行一些调整):
到目前为止,你尝试了什么?它有点不清楚。我正在计算查询中的每个条目和食物中的每个条目之间的余弦相似性。keys()@BlackThunder1000条目不多。你为什么不显示你尝试过的代码,这些代码有效,但效率低下。这将使人们更容易提出性能改进建议。输出列表不能为空。那么我们需要一份布尔人的名单?谢谢@Black Thunder。我只是在计算复杂性。您的代码将具有O(n*m)复杂性。但我认为它会起作用。
foods={
"chicken masala" : "curry",
"chicken burger" : "burger",
"beef burger" : "burger",
"chicken soup" : "appetizer",
"vegetable" : "curry"
}
queries = ["best burger", "order"]
from difflib import SequenceMatcher
out = []
for q in queries:
for k in foods:
r = SequenceMatcher(None, k, q).ratio()
print('q={: <20} k={: <20} ratio={}'.format(q, k, r))
if r > 0.5:
out.append(k)
print(out)
q=best burger k=chicken masala ratio=0.16
q=best burger k=chicken burger ratio=0.64
q=best burger k=beef burger ratio=0.8181818181818182
q=best burger k=chicken soup ratio=0.2608695652173913
q=best burger k=vegetable ratio=0.3
q=order k=chicken masala ratio=0.10526315789473684
q=order k=chicken burger ratio=0.3157894736842105
q=order k=beef burger ratio=0.375
q=order k=chicken soup ratio=0.11764705882352941
q=order k=vegetable ratio=0.14285714285714285
['chicken burger', 'beef burger']