我有一个Python 2.7设置对象,其中包含数据类别的名称,我希望能够进行某种形式的模糊元素检查,以查看给定输入的用户部分是否是该集合的元素。 / p>
这是一个玩具示例,用于解释我想要的内容。给出以下设置和用户输入:
SET = {'red_ball', 'green_ball', 'red_cup', 'green_cup'}
user_input = 'yellow ball'
我希望程序打印出如下内容:
'yellow_ball' not found, did you mean 'red_ball', or 'green_ball'?
到目前为止,我有以下内容:
import re
SET = {'red_ball', 'green_ball', 'red_cup', 'green_cup'}
user_input = 'yellow ball'
# all members of my set are lowercase and separated by an underscore
user_input_list = user_input.lower().split() # for use in fuzzy search
user_input = "_".join(user_input_list) # convert to yellow_ball for element check
regex = None
matches = []
if user_input not in SET:
# FUZZY ELEMENT CHECK
for item in user_input_list:
regex = re.compile(item)
for element in SET:
if regex.match(element):
matches.append(element)
if len(matches) > 0:
print '\'%s\' not found, did you mean %s' % (user_input, ", ".join(['\'' + x + '\'' for x in matches]))
else:
print '\'%s\' not found.' % user_input
是否有更有效的方法可以使用第三方库?
感谢您的帮助, 杰兰特
答案 0 :(得分:2)
如果您对第三方模块感兴趣,那么我喜欢使用这个名为fuzzywuzzy
的小模块,用于Python中的模糊字符串匹配。
该模块仅使用几行代码执行模糊字符串匹配。
以下是如何使用它的示例:
>>> from fuzzywuzzy import process
>>> choices = {'red_ball', 'green_ball', 'red_cup', 'green_cup'}
>>> query = 'yellow ball'
我们已经设置了我们的选择和输入,现在我们可以检索最接近的匹配。
>>> process.extract(query, choices)
[('red_ball', 53), ('green_ball', 48), ('red_cup', 13), ('green_cup', 10)]
以匹配接近度的降序返回所有选项。使用Levenshtein距离度量计算字符串之间的距离。如果原始输入不在选项集中,您可以提取前n
项并将其作为有效替代项提出。
如果您只想要最匹配,请执行以下操作:
>>> process.extractOne(query, choices)
('red_ball', 53)
您可以使用模糊字符串匹配here来仔细阅读更多示例。
答案 1 :(得分:1)
重写你的程序。删除了正则表达式。不知道你是否想要下划线或空格作为单词分隔符(这可以很容易地改变)。
SET = ( 'red ball', 'green ball', 'red cup', 'green cup')
# For each element in the set, build a list of words
WORDS = {}
for s in SET:
WORDS[s] = list( s.split(' ') )
# get user input
user_input = 'yellow ball'
if user_input not in SET:
# determine possible answers
input_words = user_input.split(' ')
other_answers = []
for s in WORDS:
if any(w in WORDS[s] for w in input_words):
other_answers.append(s)
# print result
if len(other_answers) > 0:
print "'%s' not found, did you mean %s" % (
user_input,
", or ".join(["'%s'" % oa for oa in other_answers])
)
else:
print "'%s' not found" % user_input