user6142489
user6142489

Reputation: 532

Python: Reading in Dictionary from Textfile

I have an ugly problem I've come across. I'm being fed the following text file, which is output from another Python file. From that previous file, it's a dictionary that was spit out into this text file.

Text file (named 'output.txt'):

0:[([(11, 191), (11, 170), (14, 170), (11, 188)], [0.7830932724146064, 0.7789413675533634, 0.7714495149543579, 0.7688444764225846])]
90:[([(95, 170), (95, 2), (119, 2), (95, 146)], [0.7830932724146064, 0.7789413675533634, 0.7714495149543579, 0.7688444764225846])]
180:[([(182, 2), (182, 23), (179, 23), (182, 5)], [0.7830932724146064, 0.7789413675533634, 0.7714495149543579, 0.7688444764225846])]
270:[([(98, 23), (98, 191), (74, 191), (98, 47)], [0.7830932724146064, 0.7789413675533634, 0.7714495149543579, 0.7688444764225846])]

I'm fairly familiar with reading in text files, but this one has me stumped. The silly thing about this whole problem is that I actually need the file to be given to me in a dictionary format, so I'm basically just trying to read in the file as it was given to me. The problem is when reading it in, Python doesn't know it's a dictionary and instead gives me strings. Is there anyway to have the values of the dictionary read in as a list of lists instead of just a string (shown below)? Thanks very much!

d = {}
with open("output.txt") as f:
    for line in f:
        d_line = line.rstrip('\n').split(':')
        d[int(d_line[0])] = d_line[1]

print(d)

{0: '[([(11, 191), (11, 170), (14, 170), (11, 188)], [0.7830932724146064, 0.7789413675533634, 0.7714495149543579, 0.7688444764225846])]', 90: '[([(95, 170), (95, 2), (119, 2), (95, 146)], [0.7830932724146064, 0.7789413675533634, 0.7714495149543579, 0.7688444764225846])]', 180: '[([(182, 2), (182, 23), (179, 23), (182, 5)], [0.7830932724146064, 0.7789413675533634, 0.7714495149543579, 0.7688444764225846])]', 270: '[([(98, 23), (98, 191), (74, 191), (98, 47)], [0.7830932724146064, 0.7789413675533634, 0.7714495149543579, 0.7688444764225846])]'}

Upvotes: 1

Views: 76

Answers (2)

j-i-l
j-i-l

Reputation: 10997

You can use eval here:

dict_from_file = {}
with open('output.txt','r') as f:
    for line in f:
        d_line = line.rstrip('\n')
        dict_from_file.update(eval('{{{0}}}'.format(d_line))) 

Or to keep it compact:

with open('output.txt', 'r') as f:
    dict_from_file = eval('{{{0}}}'.format(','.join(f.readlines()))

Please note though: eval is not a save method. If you are not absolutely sure about the content you feed eval, don't use it!

A saver alternative is ast.literal_eval. You can use it just as eval here.

The best approach in this case would be to not have the first script write the dictionaries as plain text. Using something like pickles is both saver and simpler!

Upvotes: 2

Ajax1234
Ajax1234

Reputation: 71471

You are close, yo can use ast.literal_eval to interpret the rest:

import ast
d = {}
with open("output.txt") as f:
   for line in f:
      d_line = line.rstrip('\n').split(':')
      d[int(d_line[0])] = ast.literal_eval(d_line[1])

print(d)

Or in one line:

new_d = {int(key):ast.literal_eval(values) for key, values in [i.strip('\n').split(':') for i in open('output.txt')]}

Upvotes: 2

Related Questions