【问题标题】:separating only suffixes from string仅从字符串中分离后缀
【发布时间】:2021-09-02 17:07:50
【问题描述】:

我有一个单词后缀列表,我的目的是将输入的句子分成列表中的后缀。

我的问题是这个列表中的后缀甚至在词根处也将单词分开。例如:

(国际)>>应该是>>(interna _tion _al _ly),我的代码输出是>>(int _erna _tion _al _ly)

注意:我的列表中有“er”

一种解决方案是从句子末尾开始搜索单词。例如,如果匹配列表,代码首先添加字母“y”,然后将其分隔,如果不匹配,则继续添加>“ly”分隔,因为它匹配,然后重置并继续“l”>“al”并将其分开并继续。再这样下去,“erna”就不会匹配和分裂了。

如果它以这种方式搜索,问题就会消失,但我找不到解决方法。

如果你给我指路,我会很高兴的。

sentence = input()
suffixes = ["acy", "ance", "ence", "dom", "er", "or", "ism", "ist",
         "ty", "ment", "ness", "ship", "sion", "tion", "ate",
        "en", "fy", "ize", "able", "ible", "al",
        "esque", "ful", "ic", "ous", "ish", "ive",
        "less", "ed", "ing", "ly", "ward", "wise"]

for x in suffixes:
    y = " _" + x
    sentence = sentence.replace(x, y)

【问题讨论】:

  • 欢迎来到 Stack Overflow!请使用tour 并阅读How to Ask。如需调试帮助,您需要提供minimal reproducible example,包括输入(后缀列表)和代码。即使您本身不寻求调试帮助,您至少需要提供后缀列表。例如,我不知道你从哪里得到tion,因为根是“nation”,而不是“na”。
  • 不应该国际化吗?
  • @Matiiss "international" 本身有一个后缀“al”。也就是说,我不知道为什么“tion”被算作后缀,就像我上面写的那样。
  • 有点难说...没有看到你的代码,你认为我怎么会知道为什么它被算作后缀而没有看到你的代码?
  • 对不起,我忘了添加代码,现在添加

标签: python suffix


【解决方案1】:

这是一种使用endswith() 和字符串切片的方法:

suffixes = ["acy", "ance", "ence", "dom", "er", "or", "ism", "ist",
            "ty", "ment", "ness", "ship", "sion", "tion", "ate",
            "en", "fy", "ize", "able", "ible", "al",
            "esque", "ful", "ic", "ous", "ish", "ive",
            "less", "ed", "ing", "ly", "ward", "wise"]

def find_suffix(word):
    for suffix in suffixes:
        if word.endswith(suffix):
            suffix_removed = word[:-len(suffix)] # part before suffix
            return find_suffix(suffix_removed) + f' _{suffix}' # recurse
    return word # if no suffix is found, return the word as is

print(find_suffix('internationally')) # interna _tion _al _ly
print(find_suffix('egoistically')) # ego _ist _ic _al _ly

递归不是必需的;只需使用 for 循环即可。

在 Python 3.9 中,they introduced a methodremovesuffix() 为字符串,其定义与上面的代码基本相同。如果您使用的是 Python 3.9+,则可以改为使用 suffix_removed = word.removesuffix(suffix) 以提高可读性(尽管我使用 3.8 后没有对此进行测试)。


根据 OP 的要求,以下是将上述内容应用于句子中每个单词的函数。

def suffixify_sentence(sentence):
    return ' '.join(find_suffix(word) for word in sentence.split())

sentence = 'humanity internationally faithfully picturesque'
print(suffixify_sentence(sentence)) # humani _ty interna _tion _al _ly faith _ful _ly pictur _esque

【讨论】:

  • 跑题了,不过suffixes应该是个参数
  • 有趣,递归处理这类问题有什么好处吗?
  • @fthomson FWIW,它比my iterative solution 更优雅:)
  • 递归解决方案往往是简洁的,所以有话要说。我以为我很喜欢向后构建它,哈哈
  • @j1-lee 如果我们想为一个句子而不是一个词做这个怎么办?
【解决方案2】:

str.replace() 是问题所在。它替换子字符串anywhere,而不仅仅是在末尾。相反,您可以使用 str.endswith(),或者如果您使用的是 3.9+,则可以使用 str.removesuffix()

这是一个使用str.endswith() 的迭代实现。

def remove_suffixes(string, suffixes):
    """
    Remove all suffixes from string. Return the root and suffixes.

    >>> remove_suffixes('smartly', ['y', 'ly'])
    ('smart', ['ly'])
    """
    # Sort to ensure the longest ones match first
    suffixes = sorted(suffixes, key=len, reverse=True)
    removed = []
    prev = None  # Loop variable
    while prev != string:  # i.e. break if unchanged
        prev = string  # Copy for next loop
        for suffix in suffixes:
            if string.endswith(suffix):
                removed.append(suffix)
                string = string[:-len(suffix)]
    return string, removed[::-1]

suffixes = [
    "acy", "ance", "ence", "dom", "er", "or", "ism", "ist",
    "ty", "ment", "ness", "ship", "sion", "tion", "ate",
    "en", "fy", "ize", "able", "ible", "al",
    "esque", "ful", "ic", "ous", "ish", "ive",
    "less", "ed", "ing", "ly", "ward", "wise"]

s_out, found = remove_suffixes('internationally', suffixes)
# > 'interna', ['tion', 'al', 'ly']
print(s_out, *found, sep=' _')  # -> interna _tion _al _ly

【讨论】:

    【解决方案3】:

    我不确定您的算法是否适用于所有情况,但实现起来似乎很有趣,所以在这里

    sentence = 'internationally'
    sentence = list(sentence)
    stack = []
    results = []
    for i in sentence[::-1]:
        stack.insert(0,i)
        guess = ''.join(stack)
        if guess in suffixes:
            results.insert(0, f'_{guess}')
            stack = []
    
    results.insert(0, guess)
        
    print(''.join(results))
    # interna_tion_al_ly    
    

    你实际上实现了一个堆栈并向后构建它

    【讨论】:

      【解决方案4】:

      你可以的

      max_length = max(len(suffix) for suffix in suffixes)
      for suffix_length in range(max_length):
          if suffix_length >= len(word):
              break
          if word[-suffix_length:] in suffixes:
              #split suffix
      

      另一种策略是以增加长度的方式遍历后缀。您可以通过在遍历后缀之前使用 suffixes = sorted(suffixes, key = len) 来做到这一点。即:

      sentence = input()
      suffixes = ["acy", "ance", "ence", "dom", "er", "or", "ism", "ist",
           "ty", "ment", "ness", "ship", "sion", "tion", "ate",
          "en", "fy", "ize", "able", "ible", "al",
          "esque", "ful", "ic", "ous", "ish", "ive",
          "less", "ed", "ing", "ly", "ward", "wise"]
      
      suffixes = sorted(suffixes, key = len)
      for x in suffixes:
          y = " _" + x
          sentence = sentence.replace(x, y)
      

      【讨论】:

      • 第二种策略不行,试试“freedomwise”,输出是“fre _e _dom _wise”,应该是“free _dom _wise”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 2018-07-13
      • 2016-11-27
      相关资源
      最近更新 更多