srek
srek

Reputation: 323

string to OrderedDict conversion in python

i have created a python Ordered Dictionary by importing collections and stored it in a file named 'filename.txt'. the file content looks like

OrderedDict([(7, 0), (6, 1), (5, 2), (4, 3)])

i need to make use of this OrderedDict from another program. i do it as

myfile = open('filename.txt','r')
mydict = myfile.read()

i need to get 'mydict' as of Type

<class 'collections.OrderedDict'>

but here, it comes out to be of type 'str'.
is there any way in python to convert a string type to OrderedDict type? using python 2.7

Upvotes: 4

Views: 6291

Answers (4)

oogieoogieful
oogieoogieful

Reputation: 13

Here's how I did it on Python 2.7

from collections import OrderedDict
from ast import literal_eval

# Read in string from text file
myfile = open('filename.txt','r')
file_str = myfile.read()

# Remove ordered dict syntax from string by indexing
file_str=file_str[13:]
file_str=file_str[:-2]

# convert string to list
file_list=literal_eval(file_str)

header=OrderedDict()
for entry in file_list:
    # Extract key and value from each tuple
    key, value=entry
    # Create entry in OrderedDict
    header[key]=value

Again, you should probably write your text file differently.

Upvotes: 0

Guray Celik
Guray Celik

Reputation: 1281

This is not a good solution but it works. :)

#######################################
# String_To_OrderedDict
# Convert String to OrderedDict
# Example String
#    txt = "OrderedDict([('width', '600'), ('height', '100'), ('left', '1250'), ('top', '980'), ('starttime', '4000'), ('stoptime', '8000'), ('startani', 'random'), ('zindex', '995'), ('type', 'text'), ('title', '#WXR#@TU@@Izmir@@brief_txt@'), ('backgroundcolor', 'N'), ('borderstyle', 'solid'), ('bordercolor', 'N'), ('fontsize', '35'), ('fontfamily', 'Ubuntu Mono'), ('textalign', 'right'), ('color', '#c99a16')])"
#######################################
def string_to_ordereddict(txt):

    from collections import OrderedDict
    import re

    tempDict = OrderedDict()

    od_start = "OrderedDict([";
    od_end = '])';

    first_index = txt.find(od_start)
    last_index = txt.rfind(od_end)

    new_txt = txt[first_index+len(od_start):last_index]

    pattern = r"(\(\'\S+\'\,\ \'\S+\'\))"
    all_variables = re.findall(pattern, new_txt)

    for str_variable in all_variables:
        data = str_variable.split("', '")
        key = data[0].replace("('", "")
        value = data[1].replace("')", "")
        #print "key : %s" % (key)
        #print "value : %s" % (value)
        tempDict[key] = value

    #print tempDict
    #print tempDict['title']

    return tempDict

Upvotes: 0

Gareth Latty
Gareth Latty

Reputation: 89077

The best solution here is to store your data in a different way. Encode it into JSON, for example.

You could also use the pickle module as explained in other answers, but this has potential security issues (as explained with eval() below) - so only use this solution if you know that the data is always going to be trusted.

If you can't change the format of the data, then there are other solutions.

The really bad solution is to use eval() to do this. This is a really really bad idea as it's insecure, as any code put in the file will be run, along with other reasons

The better solution is to manually parse the file. The upside is that there is a way you can cheat at this and do it a little more easily. Python has ast.literal_eval() which allows you to parse literals easily. While this isn't a literal as it uses OrderedDict, we can extract the list literal and parse that.

E.g: (untested)

import re
import ast
import collections

with open(filename.txt) as file:
    line = next(file)
    values = re.search(r"OrderedDict\((.*)\)", line).group(1)
    mydict = collections.OrderedDict(ast.literal_eval(values))

Upvotes: 6

wong2
wong2

Reputation: 35750

You could store and load it with pickle

import cPickle as pickle

# store:
with open("filename.pickle", "w") as fp:
    pickle.dump(ordered_dict, fp)

# read:
with open("filename.pickle") as fp:
    ordered_dict = pickle.load(fp)

type(ordered_dict) # <class 'collections.OrderedDict'>

Upvotes: 7

Related Questions