0

For a program I'm working on I have a text file that contains something similar to this:

{0: {2: 1, 1: 1}, 1: {2: 1, 0: 1}, 2: {0: 1, 1: 1}}

where essentially the first number is an index for a node, and the following is a list of follow up nodes this node is connected to, and their weights. I was wondering the best way to be able to grab a single set enclosed in a pair of {}'s, so I would end up with something like this:

0:
{2: 1, 1: 1}
1:
{2: 1, 0: 1}

Currently my plan is to find the index of the first colon and take what is between the open bracket and that colon as the ID, then find the next open bracket and following colon to get the following set of nodes however it is quickly becoming complicated for much larger lists and was wondering if there was a better method

RipIt
  • 205
  • 1
  • 8

1 Answers1

6

You're in luck (or is it really luck?), your format is valid python literal dict of dicts.

So you just have to:

  • use ast.literal_eval to do the heavy lifting and create the dictionary of dicts
  • iterate through the sorted items and print according to the format you want (note that the sorting of the internal dictionaries is arbitrary, if you want to control it, you have to do another loop on sorted elements again)

Code:

import ast

s = "{0: {2: 1, 1: 1}, 1: {2: 1, 0: 1}, 2: {0: 1, 1: 1}}"
dict_of_dicts = ast.literal_eval(s)
for k,v in sorted(dict_of_dicts.items()):
    print("{}\n{}".format(k,v))

result:

0
{1: 1, 2: 1}
1
{0: 1, 2: 1}
2
{0: 1, 1: 1}

Note that json.loads wouldn't work here because json requires double quoted strings in the dataset. Other data types aren't compatible.

More generally, if you have other separators so it's not suitable for ast.literal_eval or json, there's a nesting-capable parser module called pyparsing.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219