1

I have a text file containing python dictionaries. The thing is when I extract these dictionaries using ast.literal_eval the order changes and I know it is supposed to change as dictionaries are unordered data structures.

>>> import ast
>>> fp = open('file','r')
>>> dic = fp.readline()
>>> dic
"{'7': {'16': 'a', '15': {'10': {'9': {'8': 'a'}}, '12': {'11': 'a'}, '14': {'13': 'a'}}, '6': {'3': {'1': 'a', '2': 'a'}, '5': 'a', '4': 'a'}}}\n"
>>> dic1 = ast.literal_eval(dic.strip())
>>> dic1
{'7': {'6': {'3': {'1': 'a', '2': 'a'}, '5': 'a', '4': 'a'}, '15': {'10': {'9': {'8': 'a'}}, '12': {'11': 'a'}, '14': {'13': 'a'}}, '16': 'a'}}

I need to extract these dictionaries as ordered dictionaries as:

{'7': {'16': 'a', '15': {'10': {'9': {'8': 'a'}}, '12': {'11': 'a'}, '14': {'13': 'a'}}, '6': {'3': {'1': 'a', '2': 'a'}, '5': 'a', '4': 'a'}}}

This is what I tried but it didn't work.

>>> from collections import OrderedDict as od
>>> od(dic.strip())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/collections.py", line 52, in __init__
    self.__update(*args, **kwds)
  File "/usr/lib/python2.7/_abcoll.py", line 547, in update
    for key, value in other:
ValueError: need more than 1 value to unpack

Is there any way to extract these dictionaries as ordered dictionaries. Any help will be appreciated.

Irshad Bhat
  • 8,479
  • 1
  • 26
  • 36
  • 3
    You can't expect `OrderedDict` to take the same input as `ast.literal_eval`. If you really need it ordered, you will have to parse the string yourself. You should think very carefully about whether that's strictly necessary. Where did the data come from; could it be in a different format? – jonrsharpe Dec 10 '14 at 15:57
  • @jonrsharpe, It is strictly necessary. Actually these dictionaries are trees and I am plotting them using `pydot`. But as the order changes the tree structure also changes and thus producing wrong trees. – Irshad Bhat Dec 10 '14 at 16:03
  • @jonrsharpe, The data comes from a python script for dependency parsing of Hindi sentences and is saved as such. It'll be really tedious and time consuming to change that script to output trees in different format. – Irshad Bhat Dec 10 '14 at 16:09
  • But feasibly less time consuming and tedious than writing your own parser from a `dict.__repr__` to `OrderedDict`! – jonrsharpe Dec 10 '14 at 16:11
  • Can you post a snippet of your source file? – Hrabal Dec 11 '14 at 10:42
  • @Hrabal, I've read the first line and printed it. My source file contains more than 30 such similar lines. – Irshad Bhat Dec 11 '14 at 15:28

1 Answers1

0

Here I'm suggesting a way to do it, not the complete solution for I have no time to elaborate some fully working and optimized piece of code...

import collections

dict_names_list = []
dict_list = []
with open('file.txt','r') as txt:
    with open("dicts.py", "wt") as py:
        d = 1
        for line in txt:
            d_name = 'd'+str(d)
            dict_names_list.append(d_name)
            py.write(d_name + ' = ' + line)
            d += 1

dicts = __import__('dicts')

for d in dict_names_list:
    dict_x = collections.OrderedDict()
    dict_x = getattr(dicts, d)
    dict_list.append(dict_x)

The strategy here is to copy your txt file into a .py file, adding variable names to those dicts (d1,d2,ecc..) That way you can dinamically import them.

The code I wrote load the dicts as ordered dicts, but the order is mantained just for the first lever ok keys, inner dicts are loaded unordered..

Guess you can try to optimize this 'till a ordered dicts of ordered dicts..

edit: you also have to delete the "dict.py" file at the end of the import..

Hrabal
  • 2,403
  • 2
  • 20
  • 30
  • Sorry, this seems equivalent to the direct method as the order is not preserved. Thanks for trying. – Irshad Bhat Dec 12 '14 at 10:35
  • Unfortunately there is no "easy" way for doing this.. In your situation I'll change the program that outputs the file so it produces json data, then you can import that the way [suggested here](http://stackoverflow.com/questions/6921699/can-i-get-json-to-load-into-an-ordereddict-in-python) – Hrabal Dec 12 '14 at 10:47