Home > database >  python, when i load a dictionary using pickle, only the first key and value print when i try to prin
python, when i load a dictionary using pickle, only the first key and value print when i try to prin

Time:09-22

Good day,

The purpose of my script is to create a small dictionary that is saved to a file using pickle and print the entire contents of the dictionary for the user. My script prompts the user to make 1 of 3 choices:

Selection 1 is intended to print all contents of a dictionary loaded using pickle. Selection 2 appends to the existing dictionary and prints what was appended. Selection 3 creates a file and adds an entry into it.

When I select option 1, only the first entry prints.

When I use select option 2, I can add an entry and I can see that entry in the file that is in the same folder as the script. I am unsure what type of file it is. I can open with notepad though. The new entry also prints.

I only select option 3 once, to create the file. It adds the first entry and prints it successfully.

I need help getting the entire contents of the dictionary to print.

print("""\n 
      1- View  codes
      2- Add code
      3- Create file/add first""")

while True:
    choice = input("What is your choice?")
    
    DC_Message = {}
    
    
    if choice == "1":
        filename = "dcoutput"
        infile = open(filename, 'rb')
        DC_Message2 = pickle.load(infile)
        infile.close()
        for key, value in DC_Message2.items():
            print(key, ' : ', value)
            
            
    elif choice == "2":
        DCcode = str(input("What is the new DCcode?"))
        Message = str(input("What is the new message"))
        DC_Message[DCcode] = Message
        print(DC_Message)
        for key, value in DC_Message.items():
            outfile = open("dcoutput", 'ab')
            pickle.dump(DC_Message, outfile)
            outfile.close()
            print(key, ' : ', value)
    
    elif choice == "3":
        DCcode = str(input("What is the new DCcode?"))
        Message = str(input("What is the new message"))
        DC_Message[DCcode] = Message
        print(DC_Message)
        for key, value in DC_Message.items():
            outfile = open("dcoutput", 'wb')
            pickle.dump(DC_Message, outfile)
            outfile.close()
            print(key, ' : ', value)

  

CodePudding user response:

Trying to read between the lines here since it's not 100% clear what you are trying to do.

  1. Because there is just one object in the pickle (a dictionary) you can only read the pickle into a dictionary object or write the dictionary to the pickle.
  2. I think you are confusing appending to the dictionary with reading/writing (loading/dumping) to the pickle.
  3. You loop through every entry in the dictionary and then in that loop you dump the dictionary to the pickle file over and over and over again. No need for a loop here, just dump the dictionary to the pickle file.

Consider the following code change:

import pickle
print("""\n 
      1- Load Codes from File
      2- Add code
      3- Save Codes to file
      4- Exit program""")

#initialize dictionary outside of the loop. 
DC_Message = {}
filename = "dcoutput"

while True:
    choice = input("What is your choice?")   

    
    #LOAD dictionary from pickle file
    if choice == "1":
        print("Loading DC info from file")

        #open the pickle file, and load it to our dictionary            
        infile = open(filename, 'rb')
        DC_Message = pickle.load(infile)
        infile.close()
        for key, value in DC_Message.items():
            print(key, ' : ', value)
            
    #ADD to the dictionary (but don't save to pickle) 
    elif choice == "2":
        #get input from user
        DCcode = str(input("What is the new DCcode?"))
        Message = str(input("What is the new message"))

        #Add input to dictionary
        DC_Message[DCcode] = Message            

        #print out each entry in the dictionary     
        for key, value in DC_Message.items():           
            print(key, ' : ', value)
    
    #SAVE the dictionary to pickle file
    elif choice == "3":
        print("Writing to pickle file", DC_Message)     

        #open pickle file for writing and dump the dictionary   
        outfile = open(filename, 'wb')
        pickle.dump(DC_Message, outfile)
        outfile.close()
        print("Pickle file written")

    #exit program
    elif choice =="4":
        print("leaving program, hope you saved (option 3)")
        break

Option 1 loads the dictionary from the pickle. I changed this to use your DC_Message dictionary since that's the dictionary this code is working with.

Option 2 appends new entries to the dictionary (not the pickle).

Option 3 merely saves the dictionary to the pickle.

CodePudding user response:

Pickle does not save just dict data. It saves whole objects and one file should be used to store one pickle's dump. You cannot just append to it, like with simple text files, that's why you get only one item.

To make the code work as you described it, you should:

-Use pickle to dump dict.

-Use pickle to load dict from pickle file

-Append to dict using just dict[key] = value

-Save modified dict again using pickle.dump.

I have modified your code and I think it works the way you wanted:

import pickle


print("""\n 
      1- View  codes
      2- Add code
      3- Create file/add first""")

FILENAME = "dcoutput"

while True:
    choice = input("What is your choice?")

    DC_Message = {}

    if choice == "1":
        try:
            infile = open(FILENAME, 'rb')
            DC_dict = pickle.load(infile)
            print(DC_dict)  # Printout whole dict
            infile.close()
            for key, value in DC_dict.items():  # Your custom printout loop
                print(key, ' : ', value)
        except FileNotFoundError:
            print(f"Make {FILENAME} file before reading! (choice: 2)")

    elif choice == "2":
        DCcode = str(input("What is the new DCcode?"))
        Message = str(input("What is the new message"))

        # Try to load old dict, if FileNotFound, make new empty one.
        try:
            with open(FILENAME, 'rb') as file:
                old_dict = pickle.load(file)
        except FileNotFoundError:
            old_dict = {}

        old_dict[DCcode] = Message  # Append new data
        print(old_dict)             # Print all data to check if all working properly.

        # Overwrite file with new data
        with open(FILENAME, "wb") as file:
            pickle.dump(old_dict, file)

    elif choice == "3":
        DCcode = str(input("What is the new DCcode?"))
        Message = str(input("What is the new message"))

        new_dict = {DCcode: Message}

        # Create (or overwrite if already exist) pickle file.
        with open(FILENAME, "wb") as file:
            pickle.dump(new_dict, file)

Here you can see my console output with above code:

  • Related