Python模糊元素检查

时间:2017-07-02 15:08:34

标签: python python-2.7 set fuzzy-search

我有一个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

是否有更有效的方法可以使用第三方库?

感谢您的帮助, 杰兰特

2 个答案:

答案 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