Create nested dictionary from text file using Python 3

Viewed 3109

This is my file: test.txt

Amy|Female|Desc1|12
John|Male|Desc2|10
Mike|Male|Desc3|18

I tried to create nested dictionary and it's not sucessful.

This is the output:

{'Amy': '12', 'John': '10', 'Mike': '18'}

This is my code:

import csv
with open('test.txt') as file:
    tsvfile = csv.reader(file, delimiter='|')
    d = {}

    for row in tsvfile:
        d[row[0]] = row[0] #this should be name
        d[row[0]] = row[1] #this should be gender
        d[row[0]] = row[3] #this should be desc
        d[row[0]] = row[3] #this should be age
    print(d)

My desired output as below but was not successful.

d={1{'Name':'Amy', 'Gender':'Female', 'Desc': 'Desc1', 'Age': '12'}
 2{'Name':'John', 'Gender':'Male', 'Desc': 'Desc2', 'Age': '10'}
 3{'Name':'Mike', 'Gender':'Male', 'Desc': 'Desc3', 'Age': '18'}}

and below (with name and age only

d1={1{'Name':'Amy','Age': '12'}
 2{'Name':'John', 'Age': '10'}
 3{'Name':'Mike', 'Age': '18'}}
3 Answers

Here's how to do it without csv import, given the data format is constant:

fixed = {}
i = 1
with open("test.txt", 'r') as f:
    for line in f:
        listDetails = line.strip().split('|')
        fixed[i] = {"Name": listDetails[0]}
        fixed[i].update({"Sex": listDetails[1]})
        fixed[i].update({"Description": listDetails[2]})
        fixed[i].update({"Age": listDetails[3]})
        i+=1
print(fixed)

This should turn

Amy|Female|Desc1|12 
John|Male|Desc2|10 
Mike|Male|Desc3|18

To

{1: {'Name': 'Amy', 'Sex': 'Female', 'Description': 'Desc1', 'Age': '12'}, 2: {'Name': 'John', 'Sex': 'Male', 'Description': 'Desc2', 'Age': '10'}, 3: {'Name': 'Mike', 'Sex': 'Male', 'Description': 'Desc3', 'Age': '18'}}

Edit: Just as Nakor said though, it doesn't really make sense to make a dict of dicts here, just posted this if you really need to make it a dict.

Your desired output looks more like a list of dictionaries. In this case, I would just modify your code like this:

import csv
with open('test.txt') as file:
    tsvfile = csv.reader(file, delimiter='|')
    d = []

    for row in tsvfile:
        entry = {
          'Name': row[0],
          'Gender': row[1],
          'Desc': row[2],
        }
        d.append(entry)
    print(d)

Output:

[{'Name': 'Amy', 'Gender': 'Female', 'Desc': 'Desc1'}, 
 {'Name': 'John', 'Gender': 'Male', 'Desc': 'Desc2'}, 
 {'Name': 'Mike', 'Gender': 'Male', 'Desc': 'Desc3'}]

You can even write the loop in a more compact way like this:

keys = ["Name","Gender","Desc"]
for row in tsvfile:
    entry = { key: value for (key,value) in zip(keys,row) }
    d.append(entry)

EDIT: If you want a dictionary with the line number as keys, you can do:

import csv
with open('test.txt') as file:
    tsvfile = csv.reader(file, delimiter='|')
    d = {}
    keys = ["Name","Gender","Desc"]

    for i,row in enumerate(tsvfile):
        entry = {
          'Name': row[0],
          'Gender': row[1],
          'Desc': row[2],
        }
        d[i+1] = entry
    print(d)

1) Nested Dictionary, I have made some changes in the same code, it may help you.

import csv
with open('hello.txt') as file:
tsvfile = csv.reader(file, delimiter='|')
final_dict = {}
counter = 1
for row in tsvfile:
    d = {}
    d['Name'] = row[0] #this should be name
    d['Gender'] = row[1] #this should be gender
    d['Desc'] = row[2] #this should be desc
    d['Age'] = row[3] #this should be age
    final_dict[counter] = d
    counter+=1
print(final_dict)
Related