【问题标题】:Python fuzzy element checkingPython模糊元素检查
【发布时间】:2017-07-02 15:08:33
【问题描述】:

我有一个包含数据类别名称的 Python 2.7 集合对象,我希望能够进行某种形式的模糊元素检查,以查看用户给定输入的一部分是否是集合的元素。

这是一个玩具示例,用于解释我想要什么。给定以下集合和用户输入:

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

有没有更有效的方法来做到这一点,也许是使用第三方库?

感谢您的帮助, 杰兰特

【问题讨论】:

  • 你为什么使用正则表达式?只需使用item in element,它会做同样的事情。
  • 你的解决方案有效吗?
  • @Artyer 感谢您的推荐,我已经更改了它,它仍然可以按预期工作。
  • @GeraintBallinger 你对第 3 方库感兴趣吗?
  • @cᴏʟᴅsᴘᴇᴇᴅ 是的,我将编辑我的问题以进行澄清

标签: python python-2.7 set fuzzy-search


【解决方案1】:

如果您对第 3 方模块感兴趣,我喜欢使用一个不错的小模块来处理这种事情,称为 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 仔细阅读更多示例。

【讨论】:

    【解决方案2】:

    重写你的程序。删除了正则表达式。不知道您是否想要下划线或空格作为单词分隔符(这很容易更改)。

    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
    

    【讨论】:

      猜你喜欢
      • 2010-11-18
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多