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.