14

Let's say I have a dictionary and I want to write it into an existing file. How can I do so without losing anything that could potentially already exist in the file? What I was thinking of is doing the following:

def write_report(r, filename):
        input_filename=open(filename, "a")
        input_filename.close()
        for (k,v) in r.items():
               input_filename.write(k,v)
        return filename

what I want to make sure is that the filename correctly contains the dictionary.

Monica Heddneck
  • 2,973
  • 10
  • 55
  • 89
user300
  • 445
  • 2
  • 11
  • 20
  • In terms of the same dictionary that exists in the file or appending it to a file that already has something else? – Kyle Kelley Nov 24 '13 at 00:32

4 Answers4

25

You can use json module to read and write data structures in JSON format (in other words serialize to JSON and deserialize from JSON). For example:

import json

# load from file:
with open('/path/to/my_file.json', 'r') as f:
    try:
        data = json.load(f)
    # if the file is empty the ValueError will be thrown
    except ValueError:
        data = {}

# save to file:
with open('/path/to/my_file.json', 'w') as f:
    data['new_key'] = [1, 2, 3]
    json.dump(data, f)
Eugene Naydenov
  • 7,165
  • 2
  • 25
  • 43
7

pickle may be another choice:

import pickle

output = open('output.txt', 'ab+')
data = {'a': [1, 2, 3],}

pickle.dump(data, output)
output.close()

# read data
output = open('output.txt', 'rb')
obj_dict = pickle.load(output)    # 'obj_dict' is a dict object

But only the data that has been serialized by pickle could be read using pickle.load. So if you want to read all data from the file, you should pickle.dump all the data into the file.

flyer
  • 9,280
  • 11
  • 46
  • 62
  • 1
    The question is tagged python-3.3, where `import cPickle` is an ImportError (the accelerated version is used automatically by `import pickle` whenever it's available). – lvc Nov 24 '13 at 00:57
2

If you want to append a text representation of each key-value pair in the dictionary into a text file you could look into the following approach:

def write_report(r, filename):
    input_file=open(filename, "a")
    for k, v in r.items():
        line = '{}, {}'.format(k, v) 
        print(line, file=input_file)        
    input_file.close()

The above can be expressed more cleanly with the with statment.

def write_report(r, filename):    
    with open(filename, "a") as input_file:
        for k, v in r.items():
            line = '{}, {}'.format(k, v) 
            print(line, file=input_file)
mediocrity
  • 437
  • 4
  • 5
0

What you've already done using open(filename, "a") uses append mode - which is nearly all you need. In append mode, you'll never overwrite what's already in the file. The problem is that it doesn't guarantee you're the only one writing - and if any writes might be partial, they may come out garbled if there are ever multiple writers working on the same file. That sort of issue can be avoided using file locking.

The code you posted has a couple more problems, however, such as closing the file before writing to it, and the fact that write only accepts one string argument. You'll want to serialize data into manageable chunks, for which Python's own standard module is pickle (and shelve stores things in database files), and JSON is a more widely supported format.

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26