Reputation: 13
I have a file with two column as shown below
-34G trendmar
+41G trendmar
1.4G ttpsenet
3.6G tyibahco
-13M uberhelp
+19M uberhelp
-8.9G umljgate
+9.2G umljgate
I want to store it in dictionaries to do some mathematical operations but using the first column as value and second as key.
How could I do that?
Upvotes: 1
Views: 74
Reputation: 25789
You can read your file line by line, split on whitespace and use the elements in reverse to create a dictionary:
with open("your_file", "r") as f: # open the file for reading
# read it line by line, split and invert the fields to use as k:v for your dict
data = dict(reversed(line.split()) for line in f)
# {'trendmar': '+41G', 'ttpsenet': '1.4G', 'tyibahco': '3.6G',
# 'uberhelp': '+19M', 'umljgate': '+9.2G'}
Beware that dict
is essentially a hash map so it cannot have duplicate keys - values of duplicate keys will be overwritten with the latest value if they occur in the file.
UPDATE: If you want to preserve all the values you'll have to store them as lists, something like:
import collections
data = collections.defaultdict(list) # initiate all fields as lists
with open("your_file", "r") as f: # open the file for reading
for line in f: # read the file line by line
value, key = line.split() # split the line to value and key
data[key].append(value) # append the value to the list for its key
And now your data
will look like:
{'trendmar': ['-34G', '+41G'], 'ttpsenet': ['1.4G'], 'tyibahco': ['3.6G'],
'uberhelp': ['-13M', '+19M'], 'umljgate': ['-8.9G', '+9.2G']}
UPDATE 2: If you want to sum the values instead you'll first need to convert them to floats, then use regular arithmetic operations to reach the final value, so first write a function to convert from the SI shorthand notation to native float
:
QUANTIFIER_MAP = {"p": 1e15, "t": 1e12, "g": 1e9, "m": 1e6, "k": 1e3}
def si_to_float(number):
try:
last_char = number[-1].lower()
if last_char in QUANTIFIER_MAP:
return float(number[:-1]) * QUANTIFIER_MAP[last_char]
return float(number)
except ValueError:
return 0.0
Now you can substitute list
for a float
when creating data
and sum the values instead of appending:
import collections
data = collections.defaultdict(float) # initiate all fields as integers
with open("your_file", "r") as f: # open the file for reading
# read it line by line, split and invert the fields to use as k:v for your dict
for line in f: # read the file line by line
value, key = line.split() # split the line to value and key
data[key] += si_to_float(value) # convert to float and add to the value for this key
This will result in data
as:
{'trendmar': 7000000000.0, 'ttpsenet': 1400000000.0, 'tyibahco': 3600000000.0,
'uberhelp': 6000000.0, 'umljgate': 300000000.0}
If you want to return these values into a SI shortened notation, you'll have to write the opposite function of si_to_float()
and then convert all your data
values using it, i.e.:
QUANTIFIER_STACK = ((1e15, "p"), (1e12, "t"), (1e9, "g"), (1e6, "m"), (1e3, "k"))
def float_to_si(number):
for q in QUANTIFIER_STACK:
if number >= q[0]:
return "{:.1f}".format(number / q[0]).rstrip("0").rstrip(".") + q[1].upper()
return "{:.1f}".format(number).rstrip("0").rstrip(".")
# now lets traverse the previously created 'data' and convert its values:
for k, v in data.items():
data[k] = float_to_si(v)
This will, finally, result in data
containing:
{'trendmar': '7G', 'ttpsenet': '1.4G', 'tyibahco': '3.6G',
'uberhelp': '6M', 'umljgate': '300M'}
Upvotes: 4
Reputation: 7844
Assuming that you want more values to be associated with your keys for your calculations, this is my approach:
d = {}
with open("input.txt") as infile:
lines = infile.readlines()
keys = sorted(set(line.split()[1] for line in lines))
for key in keys:
tempList = []
for line in lines:
if line.split()[1]==key:
tempList.append(line.split()[0])
d.update({key:tempList})
print(d)
Output:
{'trendmar': ['-34G', '+41G'], 'uberhelp': ['-13M', '+19M'], 'umljgate': ['-8.9G', '+9.2G'], 'ttpsenet': ['1.4G'], 'tyibahco': ['3.6G']}
Edit:
If you wish to find the difference between two values, you can do it using the literal_eval
function from ast
module as follows:
from ast import literal_eval
d = {'trendmar': ['-34G', '+41G'], 'uberhelp': ['-13M', '+19M'], 'umljgate': ['-8.9G', '+9.2G'], 'ttpsenet': ['1.4G'], 'tyibahco': ['3.6G']}
first = 0
second = 1
diff = []
for key in d.keys():
if len(d[key])==2:
diff.append(key + " : " + str(literal_eval("".join([d[key][first][:-1] ," - (", d[key][second][:-1], ")"]))) + d[key][first][-1])
else:
diff.append(key + " : " + str(literal_eval(str(d[key][0][:-1]))) + d[key][0][-1])
print(diff)
Output:
['uberhelp : -32M', 'tyibahco : 3.6G', 'ttpsenet : 1.4G', 'umljgate : -18.1G', 'trendmar : -75G']
In the above example, we subtract the first from the second value. If you wish the opposite, then swap values of first
and second
.
Upvotes: 1
Reputation: 6748
with open("file.txt","r") as file:
print({e.split(" ")[1]:e.split(" ")[0] for e in file})
You could use dictionary comprehension
Upvotes: 2