简体   繁体   中英

Storing data of a dict in Json

I have a simple program that take input from user and put them into a dict. After then I want to store that data into json file (I searched and found only json useful)

for example

mydict = {}

while True:
    user = input("Enter key: ")
    if user in mydict.keys(): #if the key already exist only print
        print ("{} ---> {}".format(user,mydict[user]))
        continue

    mn = input("Enter value: ")
    app = input ("Apply?: ")

    if app == "y":
        mydict[user] = mn
        with open ("mydict.json","a+") as f:
            json.dump(mydict,f)

    with open ("mydict.json") as t:
        mydict = json.load(t)

Every time user enter a key and value, I want to add them into dict, after then store that dict in json file. And every time I want to read that json file so I can refresh the dict in program.

Those codes above raised ValueError: Extra data: . I understood error occured because I'm adding the dict to json file every time so there are more than one dict. But how can I add whole dict at once? I didn't want to use w mode because I don't want to overwrite the file and I'm new in Json.

Program must be infinite and I have to refresh dict every time, that's why I couldn't find any solution or try anything, since I'm new on Json.

If you want to use JSon, then you will have to use the 'w' option when opening the file for writing. The 'a+' option will append your full dict to the file right after its previously saved version.

Why wouldn't you use csv instead ? With 'a+' option, any newly entered user info will be appended to the end of the file and transforming its content at reading time to a dict is quite easy and should look something like:

import csv
with open('your_dict.json', 'r') as fp:
    yourDict = {key: value for key,value in csv.reader(fp, delimiter='\t')

while the saving counterpart would look like:

yourDictWriter = csv.writer( open('your_dict.json','a+'), delimiter='\t') )
#...
yourDictWriter.writerow([key, value]) 

Another approach would be to use MongoDB, a database designed for storing json documents. Then you won't have to worry about overwriting files, encoding json, and so on, since the database and driver will manage this for you. (Also note that it makes your code more concise.) Assuming you have MongoDB installed and running, you could use it like this:

import pymongo
client = MongoClient()
db = client.test_database.test_collection

while True:
    user = input("Enter key: ")
    if db.find_one({'user': user}) #if the key already exist only print
        print ("{} ---> {}".format(user, db.find_one({'user':user})['value'])
        continue

    mn = input("Enter value: ")
    app = input ("Apply?: ")

    if app == "y":
        db.insert({'user':user, 'value':value})

With your code as it is right now, you have no reason to append to the file. You're converting the entire dict to JSON and writing it all to file anyway, so it doesn't matter if you lose the previous data. a is no more efficient than w here. In fact it's worse because the file will take much more space on disk.

Using the CSV module as Schmouk said is a good approach, as long as your data has a simple structure. In this case you just have a table with two columns and many rows, so a CSV is appropriate, and also more efficient.

If each row has a more complex structure, such as nested dicts and or lists, or different fields for each row, then JSON will be more useful. You can still append one row at a time. Just write each row into a single line, and have each row be an entire JSON object on its own. Reading files one line at a time is normal and easy in Python.

By the way, there is no need for the last two lines. You only need to read in the JSON when the program starts (as Moses has shown you) so you have access to data from previous runs. After that you can just use the variable mydict and it will remember all the keys you've added to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM