Creating nested dictionary from text file in python3

Viewed 55

I have a text file of thousands of blocks like this. For processing I needed to convert it into dictionary.

Text file Pattern

[conn.abc]
domain = abc.com
id = Mike
token = jkjkhjksdhfkjshdfhsd

[conn.def]
domain = efg.com
id = Tom
token = hkjhjksdhfks

[conn.ghe]
domain = ghe.com
id = Jef
token = hkjhadkjhskhfskdj7979

Another sample data

New York 
domain = Basiclink.com 
token = eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiJodHRwczovL21zLmNvbS9zbm93 
method = http 
username = abc@comp.com 

Toronto 
domain = hollywoodlink.com 
token = eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiJodHRwczovL21zLmNvbS9zbm93Zmxha2UvsfdsdcHJvZGJjcy1lYXN0LXVzLTIiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9lMjliODE 
method = http 
username = abc@comp.com

Would like to convert it into following.

d1={conn.abc:{'domain':'abc.com','id': 'Mike',token:'jkjkhjksdhfkjshdfhsd'}
 conn.def:{'domain':'efg.com', 'id': 'Tom',token:'hkjhjksdhfks'}
 conn.ghe:{'domain':'ghe.com', 'id': 'Jef',token:'hkjhadkjhskhfskdj7979'}}

Thanks

2 Answers

You can use standard configparser module:

import configparser

config = configparser.ConfigParser()
config.read("name_of_your_file.txt")

Then you can work with config as standard dictionary:

for name_of_section, section in config.items():
    for name_of_value, val in section.items():
        print(name_of_section, name_of_value, val)

Prints:

conn.abc domain abc.com
conn.abc id Mike
conn.abc token jkjkhjksdhfkjshdfhsd
conn.def domain efg.com
conn.def id Tom
conn.def token hkjhjksdhfks
conn.ghe domain ghe.com
conn.ghe id Jef
conn.ghe token hkjhadkjhskhfskdj7979

Or:

print(config["conn.abc"]["domain"])

Prints:

abc.com

Since the input file can have varying # of lines with data, this code should work.

Assumptions:

  1. Each key (eg: conn.abc) will start with open square bracket and end with open square bracket. example [conn.abc]
  2. Each inner dictionary key value will be separated by =

If the key value can either be [key] or key, then use the below line of code instead of the commented line of code.

    elif '=' not in line:
    #elif line[0] == '[' and line[-1] == ']':

Code for this is:

with open('abc.txt', 'r') as f:
    d1 = {}
    for i, line in enumerate(f):
        line = line.strip()
        if line == '': continue
        elif line[0] == '[' and line[-1] == ']':
            if i !=0: d1[dkey]= dtemp
            dkey = line[1:-1]
            dtemp = {}
        else:
            line_key,line_value = line.split('=')
            dtemp[line_key.strip()] = line_value.strip()
    d1[dkey]=dtemp

print (d1)

If the input file is:

[conn.abc]
domain = abc.com
id = Mike
token = jkjkhjksdhfkjshdfhsd

[conn.def]
domain = efg.com
id = Tom
dummy = Test
token = hkjhjksdhfks

[conn.ghe]
domain = ghe.com
id = Jef
token = hkjhadkjhskhfskdj7979

The output will be as follows:

{'conn.abc': {'domain': 'abc.com', 'id': 'Mike', 'token': 'jkjkhjksdhfkjshdfhsd'}, 
 'conn.def': {'domain': 'efg.com', 'id': 'Tom', 'dummy': 'Test', 'token': 'hkjhjksdhfks'}, 
 'conn.ghe': {'domain': 'ghe.com', 'id': 'Jef', 'token': 'hkjhadkjhskhfskdj7979'}}

Note here that I added dummy = Test as a key value for conn.def. So your output will have that additional key:value in the output.

Related