Shey
Shey

Reputation: 45

Make a nested dictionary from a file

I need help with a challenge problem.

Suppose we have already loaded the file into a string viscosity_data using the read method. viscosity_data contains data (in order as gas,C,T_0,mu_0) such as:

viscosity_data = '''air,120,291.15,18.27
nitrogen,111,300.55,17.81
oxygen,127,292.25,20.18
carbon dioxide,240,293.15,14.8
carbon monoxide,118,288.15,17.2
hydrogen,72,293.85,8.76
ammonia,370,293.15,9.82
sulphur dioxide,416,293.65,12.54'''

Convert the data in the string viscosity_data into a nested dictionary mu_data such that we can look up C, T0, and μ0 for a gas with a name by mu_data[name][X], where X can be one of 'C', 'T_0', or 'mu_0'. The numerical values in mu_data should all be floats.

For instance, the following statements should be True:

mu_data['air']['C'] == 120.0
mu_data['hydrogen']['T_0'] == 293.85
mu_data['sulphur dioxide']['mu_0'] ==12.54

So far I have and I am not sure where to go from here:

mu_data = {}
#mu_data master
for data in viscosity_data:
    mu_data[name] = viscosity_data

Upvotes: 2

Views: 2130

Answers (5)

Aaditya Ura
Aaditya Ura

Reputation: 12669

Using split(',') is best approach here but many answers already on this approach so i tried with the regular expression, just wanted you to know that you can do with regex too :

import re
viscosity_data = '''air,120,291.15,18.27
nitrogen,111,300.55,17.81
oxygen,127,292.25,20.18
carbon dioxide,240,293.15,14.8
carbon monoxide,118,288.15,17.2
hydrogen,72,293.85,8.76
ammonia,370,293.15,9.82
sulphur dioxide,416,293.65,12.54'''

pattern=r"(\w.+[,])(\d.+?[,])(\d.+[.]?[,])(\d.+[.]?[^'''])"

match=re.finditer(pattern,viscosity_data)

new_dict={}

for i in match:
    new_dict[str(i.group(1)).replace(",","")]={'C': i.group(2),
        'T_0': i.group(3),
        'mu_0': "".join(i.group(4).splitlines())}

print(new_dict)

output:

{'ammonia': {'T_0': '293.15,', 'mu_0': '9.82', 'C': '370,'}, 'carbon monoxide': {'T_0': '288.15,', 'mu_0': '17.2', 'C': '118,'}, 'carbon dioxide': {'T_0': '293.15,', 'mu_0': '14.8', 'C': '240,'}, 'hydrogen': {'T_0': '293.85,', 'mu_0': '8.76', 'C': '72,'}, 'nitrogen': {'T_0': '300.55,', 'mu_0': '17.81', 'C': '111,'}, 'air': {'T_0': '291.15,', 'mu_0': '18.27', 'C': '120,'}, 'oxygen': {'T_0': '292.25,', 'mu_0': '20.18', 'C': '127,'}, 'sulphur dioxide': {'T_0': '293.65,', 'mu_0': '12.54', 'C': '416,'}}

Upvotes: 1

Ashish Ranjan
Ashish Ranjan

Reputation: 5543

You can do this using dict comprehension:

viscosity_data = '''air,120,291.15,18.27
nitrogen,111,300.55,17.81
oxygen,127,292.25,20.18
carbon dioxide,240,293.15,14.8
carbon monoxide,118,288.15,17.2
hydrogen,72,293.85,8.76
ammonia,370,293.15,9.82
sulphur dioxide,416,293.65,12.54'''

viscosity_data = [air_data.split(",") for air_data in viscosity_data.split("\n")]
mu_data = {air_name:{"c": c, "T_0": T_0, "mu_0": mu_0} for air_name,c,T_0,mu_0 in viscosity_data}

or simply in a single line using map:

mu_data = {air_name:{"c": c, "T_0": T_0, "mu_0": mu_0} for air_name,c,T_0,mu_0 
           in map(lambda x: x.split(","), viscosity_data.split("\n"))}

OUTPUT

{'air': {'T_0': '291.15', 'c': '120', 'mu_0': '18.27'},
 'ammonia': {'T_0': '293.15', 'c': '370', 'mu_0': '9.82'},
 'carbon dioxide': {'T_0': '293.15', 'c': '240', 'mu_0': '14.8'},
 'carbon monoxide': {'T_0': '288.15', 'c': '118', 'mu_0': '17.2'},
 'hydrogen': {'T_0': '293.85', 'c': '72', 'mu_0': '8.76'},
 'nitrogen': {'T_0': '300.55', 'c': '111', 'mu_0': '17.81'},
 'oxygen': {'T_0': '292.25', 'c': '127', 'mu_0': '20.18'},
 'sulphur dioxide': {'T_0': '293.65', 'c': '416', 'mu_0': '12.54'}}

Upvotes: -1

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95948

You have a csv. You should use the built-in csv module to parse it:

>>> with io.StringIO(viscosity_data) as f:
...     reader = csv.reader(f)
...     names = 'C','T_0','mu_0'
...     data = {}
...     for gas, *rest in reader:
...         data[gas] = dict(zip(names, map(float,rest)))
...

And the results:

>>> from pprint import pprint
>>> pprint(data)
{'air': {'C': 120.0, 'T_0': 291.15, 'mu_0': 18.27},
 'ammonia': {'C': 370.0, 'T_0': 293.15, 'mu_0': 9.82},
 'carbon dioxide': {'C': 240.0, 'T_0': 293.15, 'mu_0': 14.8},
 'carbon monoxide': {'C': 118.0, 'T_0': 288.15, 'mu_0': 17.2},
 'hydrogen': {'C': 72.0, 'T_0': 293.85, 'mu_0': 8.76},
 'nitrogen': {'C': 111.0, 'T_0': 300.55, 'mu_0': 17.81},
 'oxygen': {'C': 127.0, 'T_0': 292.25, 'mu_0': 20.18},
 'sulphur dioxide': {'C': 416.0, 'T_0': 293.65, 'mu_0': 12.54}}
>>>

Note, I'm using io.StringIO(viscosity_data) to pretend that the string viscosity_data is actually a file, but you should instead open up your file using the normal method.

That is, you should do:

>>> with opn("my_file.txt") as f:
...     reader = csv.reader(f)
...     names = 'C','T_0','mu_0'
...     data = {}
...     for gas, *rest in reader:
...         data[gas] = dict(zip(names, map(float,rest)))
...

Upvotes: 2

cs95
cs95

Reputation: 402413

Option 1
Using a pure-python approach (without any external packages).

data = {}
names = ['C', 'T_0', 'mu_0']
for line in viscosity_data.splitlines():
    i, *j  = line.split(',')
    data[i] = dict(zip(names, j))

Option 2
Using pandas

This is really easy if you use pandas. If you don't have it, you can install it:

pip install pandas

import pandas as pd
import io

df = pd.read_csv(io.StringIO(viscosity_data), 
            header=None, names=['gas', 'C', 'T_0', 'mu_0'])
data = df.set_index('gas').to_dict('i')

Upvotes: 2

SatanDmytro
SatanDmytro

Reputation: 537

Try:

viscosity_data = '''air,120,291.15,18.27
nitrogen,111,300.55,17.81
oxygen,127,292.25,20.18
carbon dioxide,240,293.15,14.8
carbon monoxide,118,288.15,17.2
hydrogen,72,293.85,8.76
ammonia,370,293.15,9.82
sulphur dioxide,416,293.65,12.54'''

mu_data = dict()
for line in viscosity_data.split('\n'):
    gas, C, T_0, mu_0 = line.split(',')
    mu_data[gas] = {
        'C': C,
        'T_0': T_0,
        'mu_0': mu_0
    }

print mu_data['air']['C']

Upvotes: 1

Related Questions