【问题标题】:Python - Wildcard character generating vowelsPython - 通配符生成元音
【发布时间】:2019-03-05 05:44:26
【问题描述】:

伙计们,

通过开放课件自学python,我的作业碰壁了。

基本上,用户键入带有 * 的单词作为元音。 示例:“d*g”表示 dig、dog 或 dug。

我编写的程序会将 * 替换为来自 object: vowels='aeiou' 的值,然后查看单词列表并查看是否匹配。示例:d*g -> *dag:不匹配,deg:不匹配,dig:匹配;结束搜索。

for char_vow in VOWELS:
  wildcard_word=word.replace('*',char_vow)
  print(wildcard_word)
  if wildcard_word in word_list:
      word=wildcard_word
      break

当有一个“*”时,这很有效,但我的程序无法处理两个或更多。例如,如果用户输入 d**th 表示死亡,代码只会检查 daath, deeth, diith, dooth, duuth 然后返回一个 false。

然后我认为递归可能是答案并写了:

def wildcard_replacement(word):
    wildcard_word=""
    if word.find('*')==-1:
        return word
    else:
        for char_vow in VOWELS:
              wildcard_word=word.replace('*',char_vow,1)
              print(wildcard_word)
              if wildcard_word in word_list:
                  word=wildcard_word
                  break
              elif wildcard_word.find('*')!=-1:
                  return wildcard_replacement(wildcard_word)
        return wildcard_replacement(wildcard_word)

    print(wildcard_replacement(word))

此程序搜索:daath,daeth,daith,daoth,dauth 然后停止。事后看来,这是有道理的。不再有 *。但我希望第一个元音现在从 a 翻转到和 e,然后继续第二个通配符的替换循环。我被卡住了……

有什么建议吗?

【问题讨论】:

    标签: python string recursion replace


    【解决方案1】:

    那是因为你在elif 分支中做了一个return(在你的for 下)。 所以基本上,你永远不会遍历上层的所有元音,因为一旦你停止了 * 并替换它,就没有更多了......

    建议(因为看来您实际上并不想要“code”回复):

    1. 在极限情况下(即没有*时)检查该词是否属于您的字典(word_list);
    2. 始终向函数发送临时结果(在您替换 * 之一之后);
    3. 如果你想break 在第一次遇到有效单词时,我会检查调用wildcard_replacement 的结果而不是不同的东西(你实际上是对wildcard_word 进行验证而不是返回值);李>

    【讨论】:

    • 这帮了很多忙!现在一切就绪!谢谢。
    【解决方案2】:

    递归函数是个好主意

    def expand_vowels(word):
    

    如果我们在word 中没有通配符,我们产生不变的单词并使用return 语句表示递归结束

        if '*' not in word: yield word ; return
    

    如果我们在这里,word 中至少有一个 '*'

        for new_word in (word.replace('*', vw, 1) for v in 'aeiou'):
            for new2_word in expand_vowels(new_word): yield new2_word
    

    通过一些简单的测试也很容易将所有这些放在一起

    $ cat vow.py
    def expand_vowels(word):
        if '*' not in word: yield word ; return
        for new_word in (word.replace('*', v, 1) for v in 'aeiou'):
            for new2_word in expand_vowels(new_word): yield new2_word
    
    for w in ('a', 'a*', 'a**'):
        print(list(expand_vowels(w)))
    
    good = ['aei', 'bwe']
    
    for wild in ('a**', 'b**'):
        for word in expand_vowels(wild):
            if word in good:
                print(word, 'is in the good words')
                break
        else:
            print(wild, 'doesn\'t generate a good word')
    
    $ python vow.py
    ['a']
    ['aa', 'ae', 'ai', 'ao', 'au']
    ['aaa', 'aae', 'aai', 'aao', 'aau', 'aea', 'aee', 'aei', 'aeo', 'aeu', 'aia', 'aie', 'aii', 'aio', 'aiu', 'aoa', 'aoe', 'aoi', 'aoo', 'aou', 'aua', 'aue', 'aui', 'auo', 'auu']
    aei is in the good words
    b** doesn't generate a good word
    $
    

    【讨论】:

      【解决方案3】:

      你可以在这里做的是使用 itertools 产品 你可以指定 death 示例中所需的元音组合,它将是 2 然后我们可以设置 repeat = 2 并得到所有 2 个元音字母组合,然后我们可以使用 str.replace'**' 替换为元音组合,直到我们得到 wordbank 中的匹配项

      from itertools import product
      
      vowels = 'aeiou'
      wordbank = ['death']
      word = 'd**th'
      x = word.count('*')
      
      l = [''.join(i) for i in [*product(vowels, repeat = x)]]
      print(l)
      
      for i in l:
          guess = word.replace('**', i)
          if guess in wordbank:
              print(guess)
              break
      
       death
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-03
        • 1970-01-01
        • 2015-07-02
        • 2017-03-12
        • 1970-01-01
        • 2020-08-19
        • 2021-02-03
        • 1970-01-01
        相关资源
        最近更新 更多