函数无法正确检测字符串大小写

时间:2018-12-13 03:28:53

标签: python

我正在创建一个简单的子手游戏程序,其中的密码是从大型词典(300,000多个单词)中选择的。我正在用一个更小的字典来测试代码,而我想要过滤掉的东西之一就是任何包含大写字母的单词。我一直在尝试这样做,但是目前我的代码只会过滤掉一些包含大写或完全大写的单词。

代码如下:

class Hangman(object):
    def __init__(self, level=5, non_ascii=False, dictionary='ezdict.txt', allow_uppercase=False, non_alpha=False):

        global os
        import os
        import random

        self.level = level
        self.score = 0
        self.loss = 6
        self.wordbank = []
        self.used_letters = []
        self.game_dict = []

        self.empty_gallows = " _____\n |   |\n |\n |\n |\n |\n |\n |\n_|_________\n|/       \|\n|         |"
        self.first_gallows = " _____\n |   |\n |   O\n |\n |\n |\n |\n |\n_|_________\n|/       \|\n|         |"
        self.second_gallows = " _____\n |   |\n |   O\n |   |\n |\n |\n |\n |\n_|_________\n|/       \|\n|         |"
        self.third_gallows = " _____\n |   |\n |   O\n |  /|\n |\n |\n |\n |\n_|_________\n|/       \|\n|         |"
        self.fourth_gallows = " _____\n |   |\n |   O\n |  /|\\\n |\n |\n |\n |\n_|_________\n|/       \|\n|         |"
        self.fifth_gallows = " _____\n |   |\n |   O\n |  /|\\\n |  /\n |\n |\n |\n_|_________\n|/       \|\n|         |"
        self.sixth_gallows = " _____\n |   |\n |   O\n |  /|\\\n |  / \\\n |\n |\n |\n_|_________\n|/       \|\n|         |"
        self.gal_list = [self.empty_gallows, self.first_gallows, self.second_gallows, self.third_gallows, self.fourth_gallows, self.fifth_gallows, self.sixth_gallows]

        with open(dictionary, 'r') as file:
            self.words = file.read().split('\n')

        for i in self.words:
            if (len(i) <= self.level) and (len(i) > 0):
                self.game_dict.append(i)

        if non_ascii == False:
            for i in self.game_dict:
                try:
                    i.encode('ascii')
                except UnicodeEncodeError:
                    self.game_dict.remove(i)

        if non_alpha == False:
            for i in self.game_dict:
                if i.isalpha() != True:
                    self.game_dict.remove(i)

        if allow_uppercase == False:
            for i in self.game_dict:
                if any(letter.isupper() for letter in i):
                    self.game_dict.remove(i)

        self.secret_word = random.choice(self.game_dict)

        for i in list(self.secret_word):
            self.wordbank.append('_')

        os.system('clear')

    def __play_again(self):
        play_again = input("Would you like to play again? Type 'yes' or 'no': ")
        if play_again == 'yes':
            Hangman().play()
        elif play_again == 'no':
            os.system('clear')
            exit
        else:
            print('Please check your input and try again.')
            self.__play_again()


    def play(self):  # Think about implementing an option to choose the word
        print(self.game_dict)  # For Testing
        print(self.gal_list[self.score])
        print('\n', ' '.join(self.wordbank))
        print('\nPREVIOUSLY GUESSED LETTERS:', ' '.join(self.used_letters))

        self.__user_input()

    def __user_input(self):
        print(self.secret_word)  # For testing
        self.guess = ''
        while self.guess == '':
            self.guess = input('Guess a letter: ')
            if len(self.guess) != 1:
                os.system('clear')
                print('Please guess a single letter!')
                self.play()
            elif self.guess in self.used_letters:
                os.system('clear')
                print('This letter has already been guessed.')
                self.play()
            elif len(self.guess) == 1:
                if self.guess in self.secret_word:
                    for i in range(len(self.secret_word)):
                        if self.guess == self.secret_word[i]:
                             self.wordbank[i] = self.guess
                            #print(self.wordbank)  # For testing
                else:
                    self.score += 1
            self.used_letters += self.guess
            win_check = ''
            for i in self.wordbank:
                win_check += i
            if win_check == self.secret_word:
                os.system('clear')
                print("You've won the game!")
                self.__play_again()
            elif self.score == self.loss:
                os.system('clear')
                print("Sorry, you've lost this round...")
                print('The secret word was ' + str(self.secret_word) + '.')
                self.__play_again()
            else:
                os.system('clear')
                self.play()


h = Hangman()
h.play()

引起问题的部分是这样:

if allow_uppercase == False:
    for i in self.game_dict:
        if any(letter.isupper() for letter in i):
            self.game_dict.remove(i)

文本文件包含以下单词,这些单词包含在名为“ exdict.txt”的文件中:

twinkle
little
star
how
wonder
what
you
are
up
above
the
world
so
high
like
diamond
in
sky
ABC
DEF
XYZ
HIK
bourrées
günter
contraction's
bob's
o'connell

对于大写字母,似乎只检查列表中的所有其他单词,但我完全感到困惑。它应该过滤掉所有带有大写字符的单词,但其中一半始终存在。启动游戏时会打印出可用单词列表(self.game_dict)。

1 个答案:

答案 0 :(得分:2)

您是modifying the data structure while iterating over,会导致完全错误的循环

  

永远不要更改要循环的容器,因为该容器上的迭代器   不会通知您所做的更改,并且   您已经注意到,很可能会产生完全不同的循环   和/或不正确的。

相反,重新定义game_dict来过滤掉不需要的项目:

if allow_uppercase == False:
    self.game_dict = [item for item in self.game_dict
                      if not any(letter.isupper() for letter in item)]