【问题标题】:Unpickle a Python dictionary via a loop?通过循环解开 Python 字典?
【发布时间】:2014-03-04 13:17:49
【问题描述】:

我对 Python 非常陌生,我想要实现的是腌制字典,然后使用某种形式的循环(如果我的术语不正确,请道歉!)打印文件中的所有分数。

我正在使用 Python 3.3.3,这是我的尝试,用户输入一个名称和一个分数,它首先保存到一个文件中,然后我尝试打印它。但是我无法打印分数。

import pickle

# store the scores in a pickled file
def save_scores(player, score):    

    f = open("high_score.dat", "ab")
    d = {player:score}
    pickle.dump(d, f)
    f.close

# print all the scores from the file     
def print_scores():

     # this is the part that I can't get to work!
     with open("high_score.dat", "r") as f:
        try:
            for player, score  in pickle.load(f):
                print("Player: ", player, " scored : ", score)
        except EOFError:
            pass    
    f.close

def main():

    player_name = input("Enter a name: ")
    player_score = input("Enter a score: ")

    save_scores(player = player_name, score = player_score)
    print_scores()


main()

input("\nPress the Enter key to exit")   

我在 Google 上搜索过类似问题的 Stackoverflow,但我必须使用错误的术语,因为我还没有找到解决方案。

提前致谢。

【问题讨论】:

    标签: python dictionary python-3.3 pickle


    【解决方案1】:

    pickle.load(f) 将返回一个字典。如果你迭代字典,它会产生键,而不是键值对。

    要生成 key-value paris,请使用 items() 方法(如果您使用 Python 2.x,请使用 iteritems() 方法):

    for player, score  in pickle.load(f).items():
        print("Player: ", k, " scored : ", v)
    

    要取出多个字典,您需要循环:

    with open("high_score.dat", "r") as f:
        try:
            while True:
                for player, score  in pickle.load(f).items():
                    # print("Player: ", k, " scored : ", v) # k, v - typo
                    print("Player: ", player, " scored : ", score)
        except EOFError:
            pass    
    

    顺便说一句,如果你使用with 语句,你不需要自己关闭文件。

    # f.close # This line is not necessary. BTW, the function call is missing `()`
    

    【讨论】:

    • 感谢您的全面回答!我更新了我的问题以显示我使用的是 3.3.3 版。我还更新了代码以反映更改,但是我现在看到以下错误:文件“H:/Sandbox/python/save_and_print_scores.py”,第 19 行,在 print_scores for player, score in pickle.load(f).items (): TypeError: 'str' 不支持缓冲区接口
    • @IanCarpenter,可以在某处上传high_score.dat 文件吗?
    • @IanCarpenter,我在您的代码中发现了一个错字。在以下行中,kv 应替换为:print("Player: ", k, " scored : ", v)。相应地更新了答案。
    • @IanCarpenter, f.closesave_scores 函数中也缺少()。没有括号,就不会调用close方法。
    • @IanCarpenter,没问题。快乐的 Python 编程:)
    【解决方案2】:

    pickle.load 将返回您的字典 ({player:score})

    这段代码:

    for player, score  in pickle.load(f):
    

    将尝试将返回的值解压缩为一个元组。 此外,由于您忽略了异常,因此很难判断出了什么问题。

    【讨论】:

      【解决方案3】:

      我已经做了一些修复以使您的代码在 Python 2 下工作(抱歉,没有可用的 Python 3)。几个地方都变了。这里有一些注释:

      #!/bin/python2
      import pickle
      
      # store the scores in a pickled file
      def save_scores(player, score):    
          f = open("high_score.dat", "wb")  # "wb" mode instead of "ab" since there is no obvious way to split pickled objects (surely you can make it, but it seems a bit hard subtask for such task)
          d = {player:score}
          pickle.dump(d, f)
          f.close()  # f.close is a method; to call it you should write f.close()
      
      # print all the scores from the file     
      def print_scores():
      
           # this is the part that I can't get to work!
           with open("high_score.dat", "rb") as f:  # "rb" mode instead of "r" since if you write in binary mode than you should read in binary mode
              try:
                  scores = pickle.load(f)
                  for player, score  in scores.iteritems():  # Iterate through dict like this in Python 2
                      print("Player: ", player, " scored : ", score)  # player instead of k and score instead of v variables
              except EOFError:
                  pass    
           # f.close -- 1. close is a method so use f.close(); 2. No need to close file as it is already closed after exiting `where` expression.
      
      def main():
      
          player_name = raw_input("Enter a name: ")  # raw_input instead of input - Python 2 vs 3 specific
          player_score = raw_input("Enter a score: ")
      
          save_scores(player = player_name, score = player_score)
          print_scores()
      
      
      main()
      
      raw_input("\nPress the Enter key to exit")
      

      【讨论】:

        猜你喜欢
        • 2019-08-11
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 2017-09-16
        • 2019-03-28
        • 1970-01-01
        • 1970-01-01
        • 2020-02-20
        相关资源
        最近更新 更多