Frage

I am very new to Python and what I am trying to achieve is to pickle a dictionary and then use some form of loop (apologies if I have the terminology incorrect!) to print all the scores in the file.

I am using Python 3.3.3 and here is my attempt, the user enters a name and a score which is first saved to a file and then I try to print it. However I am not able to print the scores.

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")   

I have Google'd and searched Stackoverflow for similar problems but I must be using the wrong terms as I haven't found a solution.

Thanks in advance.

War es hilfreich?

Lösung

pickle.load(f) will return a dictionary. If you iterate the dictionary, it yields keys, not key-values pairs.

To yield key-value paris, use items() method (use iteritems() method if you use Python 2.x):

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

To get multiple dictionaries out, you need to loop:

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    

BTW, if you use with statement, you don't need to close the file yourself.

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

Andere Tipps

pickle.load will return your dictionary ({player:score})

this code:

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

will try to unpack the returned value as a tuple. Also, since you ignore the exception it will be hard to tell what went wrong.

I've done a few fixes to make your code work under Python 2 (no Python 3 is available, sorry). Several places were changed. Here it is with some notes:

#!/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")
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top