列表索引必须是整数而不是str(可能很容易回答)

时间:2013-10-15 20:25:51

标签: python

我最近在上一篇文章中提出了一个关于高分问题的问题。这是一个类项目,所以它应该相对简单。我仍然是这个网站的新手,所以我不确定如何干净地发布新版本,所以如果你已经阅读了部分内容我道歉。这次我将把整个程序放在这里。一切都有效,除了高分部分。当我选择在玩游戏之前检查高分列表时,输出效果很好,但是,在玩游戏后,返回主菜单然后再次检查高分我得到错误

  

列表索引必须是整数而不是str

。我认为这意味着我的原始分数列表设置不正确,但我不完全确定。这是代码,我真的很感激帮助。这个网站非常棒。

import random
loop_game = True

while loop_game:
    questions= [
                {"question": "Who won the 2012 NFL Superbowl?",
                 "answers": ["Jacksonville Jaguars",
                            "Oakland Raiders",
                            "New York Giants",
                            "Baltimore Ravens"],
                 "correct": "4"},
                {"question": "Which song was at the top of the charts in early 2001, by OutKast?",
                 "answers": ["Bootylicious",
                             "Angel",
                             "Ms. Jackson",
                             "U Got It Bad"],
                "correct": "3"},
                {"question": "How many centimeters are one inch?",
                 "answers": ["2.12",
                             "2.54",
                             "3.24",
                             "3.38"],
                "correct": "2"}]

    scores=[{'initials': None,
             'score': -500}]

#main menu
    def main_menu():
        global loop_game
        print("""
***********************************************  
Welcome to The Greatest Trivia Show on Earth!!!
***********************************************
1. Play Game
2. High Scores
3. Credits
4. Instuctions
5. Quit
""")
        needs_input = True
        while needs_input:
          selection = input("Which Selection would you like? ")
          if selection == "1":
              play_game()
              needs_input = False
          elif selection == "2":
              display_scores()
              needs_input = False
          elif selection == "3":
              credits()
              needs_input = False
          elif selection == "4":
              instructions()
              needs_input == False
          elif selection == "5":
              needs_input = False
              loop_game = False
          else:
              print("\nSelect a valid option\n")

    def play_game():
        #definitions
        global total_points
        global questions
        loop_pa = True
        total_points = 3
        random.shuffle(questions)
        counter = 0
        #gets name in case of high score
        global hs_name
        hs_name = input("What are your initials?: ")


        #main play loop
        while counter < 2:
            for j in questions:
                counter += 1
                print("\n",j["question"])
                for i, choice in enumerate(j["answers"]):
                    print(str(i+1) + ". " + choice)
                answer = str(input("\nChoose an answer 1-4: "))
                if answer == j["correct"]:
                    print("\nGood job! You keep your precious points...this time!\n")
                else:
                    print("\nSorry, that is not correct. You lose one point.\n")
                    total_points -= 1
                    print("\nTotal Points: ",  total_points)

        #all questions have been read
        print("\nThat's it, your score is: ", total_points)

        #check/append best scores list
        best_scores()

        #keep playing loop
        while loop_pa:
            keep_playing = input("Play again?  (y, n) \n")
            if keep_playing == "y":
                print("\nAwesome! Here we go! \n\n")
                loop_pa = False
                play_game()
            elif keep_playing == "n":
                print("Ahh, too bad.  Thanks for playing!")
                loop_pa = False
                main_menu()
            else:
                print("Select a valid option\n")

    def best_scores():
        for i, score in enumerate(scores):
            if total_points > score['score']:
                scores[i:i+1] = {'initials': hs_name, 'score': total_points}
                del scores[5:]
                break

    def display_scores():
        print("HIGH\tSCORES")
        for score in scores:
            print(score['initials'], "\t", score['score'])

    def instructions():
        print("""

*************
Instructions
*************
The game is quite simple:  You start out with 12 points.
You lose a point for every incorrect answer.
If you get an answer correct, your score stays the same
and you move forward through the question set.  Try to
see how many points you can keep!
         """)
        main_menu()

    def credits():
        print("\nCreated by Jessica Gregg and Jason Vignochi\n")
        main_menu()


    main_menu()

编辑:哦!错误所在的行位于(第119行)

的display_scores函数中
  

打印(得分['姓名缩写'],“\ t”,得分['得分'])

3 个答案:

答案 0 :(得分:2)

问题在于这一行:

scores[i:i+1] = {'initials': hs_name, 'score': total_points}

替换序列的子切片时,必须将其替换为另一个迭代。例如:

>>> a = [0, 1, 2, 3, 4]
>>> a[2:3] = [3] # fine
>>> a[2] = 3 # fine
>>> a[2:3] = 3
TypeError: can only assign an iterable

那么,为什么您的代码不是TypeError?因为dict实际上 是一个可迭代的 - 它就像一个键的列表。因此,当您尝试将子列表[{'initials': old_name, 'score': old_score}]替换为字典{'initials': new_initials, 'score': new_score}时,它实际看到的是['initials', 'score']

所以,稍后,当您开始尝试打印分数时,其中一个不是dict,而是字符串'initials'。并且您尝试将其用作dict,因此错误。

如果您在致电print(scores)之前和之后best_scores更容易看到此问题,并在score打印出每个display_scores

答案 1 :(得分:2)

您正在使用scores弄乱best_scores()。第一次通过后看起来像['score', 'initials']。切片赋值需要一个可迭代的,当用作可迭代时,dict肯定会迭代其键。试试这个,看起来有点简单(虽然我可能只是追加和排序):

def best_scores():
    global scores
    for i, score in enumerate(scores):
        if total_points > score['score']:
            scores.insert(i, {'initials': hs_name, 'score': total_points})
            scores = scores[:5]
            break

我的方式:

from operator import itemgetter

def best_scores():
    global scores
    scores.append({'initials': hs_name, 'score': total_points})
    scores = sorted(scores, key=itemgetter('score'), reverse=True)[:5]

答案 2 :(得分:-1)

您使用scores[{}]定义为列表列表,以便按照您想要的方式引用它,使用scores[ 0 ][ 'initial' ]等。