Convert a file to a list of dictionaries

I have file formatted like this:

MN_N3 net48 sout VSS VBN lvtnfet l=0.116u nf=1 M=1 nfin=4 
MN_N10 net082 net48 VSS VBN lvtnfet l=0.116u nf=1 M=1 nfin=4 
MN_N11 nclk_net CK VSS VBN lvtnfet l=0.068u nf=1 M=1 nfin=4 
MN_N9 SO SE net082 VBN lvtnfet l=0.116u nf=1 M=1 nfin=4 

I want to read it as list of dictionaries such that each line forms a dictionary like this

{'name': 'MN_N3' , 'source': 'net48' , 'gate': 'sout', 'Drain':'VSS'}

I have tried this:

d{'name':line.split(' ')[0], 'source':line.split(' ')[1], 'gate':line.split(' ')[2], 'drain':line.split(' ')[3]}

Which gave me:

File "task2.py", line 24
  d{'name':line.split(' ')[0], 'source':line.split(' ')[1], 'gate':line.split(' ')[2], 'drain':line.split(' ')[3]}
   ^
SyntaxError: invalid syntax

How can I do this / fix this error?

4 answers

  • answered 2018-11-08 06:21 Modelmat

    You can't make dictionaries like that. You would have to use:

    d = {'name': line.split(' ')[0], ...}
    

    A better way of doing this, however, would be to use a for-loop.

    for line in input.split('\n'): # \n is the new line character
        for item in line.split(' '):
            print(item)
    

    This gives you every single item, and you could add each item to a dictionary by using a counter (or the enumerate function) in the inner for-loop. You could then create a list of the names and access the word by the counter's index.

  • answered 2018-11-08 06:21 Subhaditya Mukherjee

    f = open('tp.txt','r').readlines()
    for line in f:
        print({'name':line.split(' ')[0], 'source':line.split(' ')[1], 'gate':line.split(' ')[2], 'drain':line.split(' ')[3]})
    

    This will print dictionaries. You can change the print to an assignment if you want to save it .

  • answered 2018-11-08 06:25 DYZ

    The most time-saving solution is to use Pandas. It will spare you from the misery of splitting strings, forming the dictionaries, and even having loops:

    import pandas as pd
    names = ['name' , 'source', 'gate', 'Drain']
    pd.read_csv("your_file.dat", sep='\s+', header=None,
                usecols=range(len(names)), names=names).to_dict(orient='records')
    #[{'name': 'MN_N3', 'source': 'net48', 'gate': 'sout', 'Drain': 'VSS'},
    # {'name': 'MN_N10', 'source': 'net082', 'gate': 'net48', 'Drain': 'VSS'}, 
    # {'name': 'MN_N11', 'source': 'nclk_net', 'gate': 'CK', 'Drain': 'VSS'},
    # {'name': 'MN_N9', 'source': 'SO', 'gate': 'SE', 'Drain': 'net082'}]
    

  • answered 2018-11-08 06:37 Vineeth Sai

    Here's a more manageable way of doing it. It will be much easier to update this code when your requirement changes, like adding lvtnfet also to the dictionary.

    # Or file.readlines()
    ls = ['MN_N3 net48 sout VSS VBN lvtnfet l=0.116u nf=1 M=1 nfin=4',
    'MN_N10 net082 net48 VSS VBN lvtnfet l=0.116u nf=1 M=1 nfin=4',
    'MN_N11 nclk_net CK VSS VBN lvtnfet l=0.068u nf=1 M=1 nfin=4',
    'MN_N9 SO SE net082 VBN lvtnfet l=0.116u nf=1 M=1 nfin=4']
    
    
    word_list = [[word for word in item.split(' ')[:4]] for item in ls ] # Only first 4 elements from the list
    
    final_dict = {index:{'name': ls[0], 'source':ls[1], 'gate':ls[2], 'Drain': ls[3]} for index, ls in enumerate(word_list)}
    
    print(final_dict)
    

    Outputs:

     {0: {'Drain': 'VSS', 'gate': 'sout', 'name': 'MN_N3', 'source': 'net48'},
     1: {'Drain': 'VSS', 'gate': 'net48', 'name': 'MN_N10', 'source': 'net082'},
     2: {'Drain': 'VSS', 'gate': 'CK', 'name': 'MN_N11', 'source': 'nclk_net'},
     3: {'Drain': 'net082', 'gate': 'SE', 'name': 'MN_N9', 'source': 'SO'}}
    

    And here's the expanded form for final_dict dict comprehension for reference.

    final_dict = {}
    for index, ls in enumerate(word_list):
        final_dict.update({index:{'name': ls[0], 'source':ls[1], 'gate':ls[2], 'Drain': ls[3]}})
    print(final_dict)