Python Hangman - " for"循环替换所有字符,而不仅仅是正确的字符

时间:2017-08-06 12:43:26

标签: python loops for-loop replace

在我对下面的功能的理解中,如果用户键入" z"它应该遍历" zebra"中的每个字符。 如果字符与用户的输入匹配,则应将user_word中的相应字符(空白字)替换为用户的条目。否则,它应该什么也不做,并继续循环通过单词" zebra"。

因此,如果用户猜到&#34; z&#34;,它应该认识到&#34; z&#34;是变量单词中的字符0,然后用&#34; z&#34;替换 user_word 中的字符0(&#34; _____&#34;)。< / p>

相反,如果用户猜到任何正确的字母,它会替换&#34; _____&#34;中的每个字符。用户的输入。因此,如果user_guess =&#34; z&#34;,则user_word将打印为&#34; zzzzz&#34;。如果他/她猜测&#34; e&#34;,user_word打印为&#34; eeeee&#34;,依此类推。

我已经按照程序的逻辑,一步一步地,在纸面上看起来它应该工作。我在下面做错了什么?

我知道那里太多了&#34; if / else&#34;下面的陈述,我打算在一些单独的函数下压缩它们(比如&#34; correctguess()&#34;函数)。

word = "zebra"

def hangman(word):

    user_word = "_" * len(word)
    incorrect_guesses = []
    failed_guesses = 0
    user_guess = getuser()

    while user_word != word and failed_guesses < 10:
        if user_guess in word:
            for char in word:
                if char == user_guess:
                    user_word = user_word.replace(user_word[word.index(char)], user_guess)
        else:
            incorrect_guesses.append(user_guess)
            failed_guesses += 1

        print "Word: ", user_word
        print "Letters missed: ", ', '.join(incorrect_guesses)
        user_guess = getuser()

    if user_guess == word:
        print "Awesome, you got it! You win!"

    else:
        print "That's ten tries, your dude is hanging from the gallows. You lose :("

2 个答案:

答案 0 :(得分:1)

问题出在这里:

for char in word:
    if char == user_guess:
        user_word = user_word.replace(user_word[word.index(char)], user_guess)

如果角色char确实是user_guess的角色,那么user_word[word.index(char)]将是下划线角色'_',因此您可以致电:

user_word = user_word.replace('_',user_guess)

这意味着您将使用user_guess替换所有下划线,无论这些下划线是否位于user_guess位于word的位置。

您可以使用以下表达式代替for循环:

user_word = ''.join(w if w == user_guess else u for u,w in zip(user_word,word))

其工作方式如下:字符串 iterable 。如果围绕字符串编写循环,则迭代字符。通过使用zip,我们构造了两个迭代的元组。所以这里的初始运行将产生('_', 'z'), ('_', 'e'), ('_', 'b'), ('_', 'r'), ('_', 'a')。对于这些元组中的每一个,我们在u,w中解压缩这些元组(因此第一次迭代u = '_'w='z')。

然后我们使用三元运算符w if w == user_guess else u。因此,三元运算符将检查w的字符word是否与user_guess相同。如果是这样,我们知道用w替换字符,否则我们会产生u

我们使用此表达式生成的可迭代因此生成字符,并且我们''.join(..)这些一起。

所以正确的程序是:

word = "zebra"

def hangman(word):

    user_word = "_" * len(word)
    incorrect_guesses = []
    failed_guesses = 0
    user_guess = getuser()

    while user_word != word and failed_guesses < 10:
        if user_guess in word:
            user_word = ''.join(w if w == user_guess else u for u,w in zip(user_word,word))
        else:
            incorrect_guesses.append(user_guess)
            failed_guesses += 1

        print "Word: ", user_word
        print "Letters missed: ", ', '.join(incorrect_guesses)
        user_guess = getuser()

    if user_guess == word:
        print "Awesome, you got it! You win!"

    else:
        print "That's ten tries, your dude is hanging from the gallows. You lose :("

如果我设置getuser = input,我会进行以下操作:

>>> hangman('zebra')
a
Word:  ____a
Letters missed:  
b
Word:  __b_a
Letters missed:  
c
Word:  __b_a
Letters missed:  c
d
Word:  __b_a
Letters missed:  c, d
e
Word:  _eb_a
Letters missed:  c, d
f
Word:  _eb_a
Letters missed:  c, d, f
g
Word:  _eb_a
Letters missed:  c, d, f, g
h
Word:  _eb_a
Letters missed:  c, d, f, g, h
i
Word:  _eb_a
Letters missed:  c, d, f, g, h, i
j
Word:  _eb_a
Letters missed:  c, d, f, g, h, i, j
k
Word:  _eb_a
Letters missed:  c, d, f, g, h, i, j, k
l
Word:  _eb_a
Letters missed:  c, d, f, g, h, i, j, k, l
m
Word:  _eb_a
Letters missed:  c, d, f, g, h, i, j, k, l, m
n
That's ten tries, your dude is hanging from the gallows. You lose :(

答案 1 :(得分:0)

.replace()不会按照您的想法执行

.replace将第一个paramater的所有匹配替换为第二个"sentence".replace("e", "z") 。举个例子:

"szntzncz"

会给:

char

您希望在您的计划中执行的操作是,在循环浏览每个_时,将索引替换为charlist()的所有下划线index

要替换字符串的索引,您需要将其转换为''.join()的列表,然后更改所需的user_word = user_word.replace(user_word[word.index(char)], user_guess) ,然后最终转换回user_word = list(user_word) user_word[word.index(char)] = user_guess user_word = ''.join(user_word) 的字符串。

所以这一行:

z

应该是:

chars

这将为您提供5个下划线中''.join(user_word)的正确位置。

也可能值得考虑将单词1.234存储在列表中,因为这意味着每次猜到一个字母时你都不必费心转换。如果您将其存储在列表中,则只需记住在为用户显示时打印:.2。 :)