如何使用迭代和变量替换字符串中的字符? (蟒蛇)

时间:2014-02-05 13:18:55

标签: python string variables replace iteration

我在python中编写一个刽子手游戏作为大学项目的一部分,我正在尝试使用string.replace(旧的,新的)用字母替换空格(_)。我没有使用实际的字符串字符,而是尝试将变量用于“旧”和“新”。这是我到目前为止所得到的:

if validGuess == 'true':
    if guess in word:
        for letter in word:
            if letter == guess:
                word.replace(letter, guess)
            else:
                missNum = (missNum + 1)
    else:
        tryNum = (tryNum - 1)

但是,它不起作用。我没有得到任何错误,它根本不会取代空白。

我在这里做错了什么?有没有更好的方法来实现我的目标?

- 的修改 -

我试图实现@Peter Westlake的解决方案(在我看来最优雅),但我遇到了一个问题。我有一段代码将随机选择的单词转换为下划线:

#converting word to underscores
wordLength = len(word)
wordLength = (wordLength - 1)
print(wordLength) #testing
for i in range(0,wordLength):
    wordGuess = (wordGuess + '_')
print(wordGuess)

这似乎工作正常。这是字母替换的代码:

if validGuess == 'true':
    wordGuess = ''.join([letter if guess == letter else wordGuess[pos]
                         for pos, letter in enumerate(word)])

    if guess not in word:
        tryNum = (tryNum - 1)

    print(wordGuess)

但是,这是输出:

Guess a letter: a
test
Traceback (most recent call last):
  File "G:\Python\Hangman\hangman.py", line 60, in <module>
    for pos, letter in enumerate(word)])
  File "G:\Python\Hangman\hangman.py", line 60, in <listcomp>
    for pos, letter in enumerate(word)])
IndexError: string index out of range

字符串索引超出范围?这是什么意思?

3 个答案:

答案 0 :(得分:1)

str.replace() 返回新字符串,存储新值:

word = word.replace(letter, guess)

Python字符串是不可变的,不能就地更改。

但是,您要用完全相同的值替换letter; letter == guess仅在两者都是相同的字符时才为真。

我会保留一组单独的正确猜测的字母,并重建显示的下划线并每次都进行正确的猜测:

correct_guesses = set()
incorrect_guesses = set()

if guess in correct_guesses & incorrect_guesses:
    print('You already guessed that letter')

elif guess in word:
    # correct guess!
    correct_guesses.add(guess)
    display_word = ''.join(char if char in correct_guesses else '_' for char in word)

else:
    # incorrect guess!
    incorrect_guesses.add(guess)
    print('Oops, incorrect guess!')
    missNum += 1

答案 1 :(得分:1)

我想我明白你在这里得到了什么。

我可能会在现场重建字远,而不是为它保留一个持久字符串,分别保留测试字母。当用户尝试新角色时,请进行两次检查:

  1. 查看猜测字符是否已被猜到:if guess in tried。如果是这样,继续你喜欢(惩罚或忽略),但不要将字符添加到试用字符列表中。

  2. 如果没有,请查看该字符是否在目标字词中:elif guess in word。如果,请评估一些惩罚并将猜测添加到试用字符列表中。

  3. 对于任何其他结果:else。将猜测添加到试用字符列表中。

  4. 要显示用户的进度,请填写一个空白字符串。像往常一样经历目标词一次性for char in word。但是,不是尝试修改现有字符串,只需将字符添加到空白字符串的末尾(如果它在try-characters字符串中),或者如果不是,则添加下划线:show += char if char in tried else "_"。一旦for循环耗尽,请显示您已获得的内容!

    或者,使用.join使用稍微不同的迭代器:show = "".join(char if char in tried else '_' for char in word)。它会通过单词进行迭代,保留每个字母,如果它在你的试用过的字符串中,或​​者用下划线代替,如果没有,将""之间的任何内容放在它们之间(或者如果你离开的话,什么也没有,它为"")。看起来你已经知道了。

    完全重写代码的危险,这可能是它的样子:

      ## init
    word = "mauritius" # the word you're looking for. I chose this one.
    tried = str()  # initialize a list of tested characters
    tryNum = 3  # however many wrong guesses the user gets
    
      ...
    
      ## in your run loop...
    if tryNum:  # evaluates 0 as Fasle, if you didn't already know
        guess = UserInput()  # some means to get the guess from the user; a single-character string.
    
        if   guess in tried:
            print "Tried that letter already!" 
        elif guess not in word:   # the letter hasn't been tested yet, but isn't in the word, either.
            print "Wrong! %d guesses left!" % tryNum
            tryNum -= 1
            tried += guess
        else:    # the guess is new (not tried) and it's valid (in the word)
            tried += guess
    
        show = str()  # this is the string you will display. make a blank one each time.
        for char in word:
            show += char if char in tried else "_"  # if the character has been tried, add it to the output. Otherwise, an underscore.
        print show  # display the word so far
    
        if show == word:
            print "You win!" # Congratulations! You hung a man.
    
    else:  # Out of tries; the convict lives another day.
        print "Game Over!" # I am not sure how committed to this vocabulary-based execution you really are...
    

    您可以将if tryNum:while tryNum:交换,并且在初始化后它应该可以自行完成。如果您这样做,可以使用continuebreak来做一些有趣的事情,但这有点超出了您的问题的范围。

    您也可以在下一个示例中将show = str()for char in word:块替换为.join单例。将''.join(..)更改为' '.join(..)以在字符/下划线之间添加空格!

    这个压缩版本可能不像Pythonic:

    # post-init...
    if tryNum:
        guess = UserInput()
        if guess in tried: pass
        elif guess not in word:
            print "Wrong! %d guesses left!" % tryNum
            tryNum -= 1
            tried  += guess
        else: tried += guess
        show = ''.join(char if char in tried else '_' for char in word)
        if show == word: print "You win!"
    else: print "Game Over!"
    

    这不能回答你的第一个问题&#34;我做错了什么?&#34;但我认为这可能是一种更好的方式来实现你想要的东西?为您维护和扩展可能会更容易一些。

    注意:如果您想独自尝试这件事,请继续将UserInput()替换为str(raw_input("Guess a letter!"))[0]

答案 2 :(得分:0)

用相同的猜测替换一封信不会做任何事情!我想你想找到猜测字母出现的单词中的位置,并用字母替换该位置的_。为此,您需要找到字母出现的每个位置,例如使用index()方法。

例如,要替换第一次出现的猜测:

# Illustration of the principle, not the complete answer.

word = 'faq'
display = '___'

# Put in a loop, one iteration for each guess input.
guess = 'a'
display = ''.join([letter if guess == letter else display[pos]
                   for pos, letter in enumerate(word)])
print display

将打印_a_