Home > Net >  Create nested dictionary where outer dictionary are column labels and inner dictionary are row label
Create nested dictionary where outer dictionary are column labels and inner dictionary are row label

Time:11-04

I have a txt file:

:Dog : Cat or Lion : Dragon
Size : 10.2 : 20.2 : 30.5
Height : 5.4 : 10.4 : 20.7
Fat % : 0.35 : 0:20 : 0:10

I would like column labels (Dog, Cat or Lion, Dragon) as my outer dictionary.

Inner dictionary keys should be Size, Height

So if I run data['Dog'] ['Size)" 10 should be printed out and values in they inner dictionary to be strings.

I face issues with creating the inner dictionary keys...

CodePudding user response:

Here is how to do it (a bit more detailed explanation is in the other code example):

from collections import defaultdict

filename = 'myfile.txt'
with open(filename) as file:
    dct = defaultdict(dict)
    # get the first line which will be the headers
    _, *headers = file.readline().split(':')
    # iterate over the next lines
    for line in file:
        # split line by ':' to extract the row name and the data
        param, *data = line.split(':')
        # zip together headers with the data
        for animal, value in zip(headers, data):
            # add the values to the dictionary
            dct[animal.strip()][param.strip()] = value.strip()
    dct = dict(dct)

print(dct)

You can also use the built-in csv library like this:

import csv
from collections import defaultdict

file_name = 'myfile.txt'
with open(file_name, newline='') as file:
    # read the data in a dictionary iterable where it represents
    # each column name and its value in each row
    reader = csv.DictReader(file, delimiter=':')
    # create a defaultdict with the dictionary to make it easier
    # to create the inner dictionaries
    dct = defaultdict(dict)
    # iterate over rows
    for row in reader:
        # simple unpacking
        (_, param), *data = row.items()
        # you can
        # print(param, data)
        # to see what it all contains but you should understand from the names
        # iterate over the data and place the values in the dictionary
        # usage of defaultdict here allows to immediately use keys
        # for the inner dictionary
        for animal, value in data:
            dct[animal.strip()][param.strip()] = value.strip()
    # conver the dct to a normal dictionary
    dct = dict(dct)


print(dct)

CodePudding user response:

The logic is usually the hardest part of solving a programming problem. Here's the logic. You can write the code.

data = {} # empty dict
for each line in the file
    split the line by ":"
    strip leading and trailing white space from each split field
    if the first field is empty
        store the fields into a name_array
        for each subsequent field in the line
            use the field as the key of a new dict entry, where the value is an empty dict
    else
        use the first field as the_key
        for each subsequent field in the line
            get the field position (index)
            use the field position to extract the name from the name_array
            update data[name][the_key] = subsequent field

The above general logic should give you a workable solution to your program without having to use any external libraries/modules.

  • Related