Converting specific values from a dictionary to float - python-3.x

I have this dictionary
dict_X = {
'A': {'a': 371, 'b': 4925, 'c': 39, 'd': 8},
'B': {'a': 400, 'b': 4659, 'c': 37, 'd': 11},
'C': {'a': 19, 'b': 214, 'c': 1, 'd': 1},
'D': {'a': 16, 'b': 115, 'c': 0, 'd': 1}
}
I need to convert the values of 'c' and 'd' to float and find ratio of 'c' to 'd'.
I know that I have to use float() method, what I cannot figure out is how to use that for the values in a dictionary within a dictionary.
Need to convert the values to 'c' and 'd' to float to find the ratio of 'c':'d'. Thank you guys for the help.

The code you posted in the comments is almost correct, except you forgot to retain the keys for the inner dict, making the nested structures sets instead. The correct dict comprehension would be:
{outer_k: {inner_k: float(inner_v) for inner_k, inner_v in outer_v.items()} for outer_k, outer_v in dict_X.items()}
However, this converts all the values (a,b,c,d) into floats instead of just c and d. You can limit it to only those keys using the following if-else condition:
{outer_k: {inner_k: float(inner_v) if inner_k in ['c','d'] else inner_v for inner_k, inner_v in outer_v.items()} for outer_k, outer_v in dict_X.items()}
Or, since according to what you said you only need the float conversion for a calculation, just cast it before using it in that expression and leave dict_X as it is. For example,
float_ratio = float(dict_X['A']['c'])/dict_X['A']['d']
Converting just one of them is enough to make the result a float.

Related

Merge two dictionaries that have dictionaries as key values

Merge two dictionaries of dictionaries
My question is similar to this one, but the answers don't produce the right result (for me?).
Take these dictionaries:
a = {'a': {'a': 1}}
b = {'a': {'b': 2}}
I want to produce:
c = {'a': {'a': 1, 'b': 2}}
Using the answers from the quoted question, these all produce:
c = a.copy()
c.update(b)
>>
c == {'a': {'b': 2}
Consider that a and b might be more complex than this, for example:
a = {'a': {'aa': {'aaa': 1}, 'bb': {'bbb': 2}}}
b = {'a': {'bb': {'aaa': 1}, 'bb': {'bbb': 2}}}
In this case you can use
>>> a['a'].update(b['a'])
>>> a
{'a': {'a': 1, 'b': 2}}
Element in dictionary is also dictionary, so you can treat that element as dictionary.
As for more complex example I don't know what result should be. But in general, you can access elements in element as dictionary in nested for loops.

Is there a way for me to use a dictionary values to loop through a string?

What I'm trying to do here is change the values in the dictionary and then use the dictionary so that it loops through the string's elements so that it'll reflect for every instance of a key. Do any of you have a recommendation on what to do next? I think I need to set up a loop, but am unsure of what to do. Thank you.
string = 'abdcabdcadcbacb'
b = 12
dict = {'a': 50, 'b': 40, 'c': 30, 'd': 20}
for aa in dict.keys():
dict[i] -= b
#output should be 360
Edit: I also need to return the sum of the difference once it's looped through the string. The output should be 360, sorry for not making it clear.
I believe you need.
string = 'abdcabdcadcbacb'
b = 12
d = {'a': 50, 'b': 40, 'c': 30, 'd': 20}
for i in string:
if i in d:
d[i] -= b
print(d) # {'a': 2, 'b': -8, 'c': -18, 'd': -16}
If I understand your question you want to modify your dictionary first by subtracting your dictionary value with b. Then you expect the sum by iterating your string. If any character of the string matches to dictionary key then sum it.
string = 'abdcabdcadcbacb'
b = 12
sum = 0
my_dict = {'a': 50, 'b': 40, 'c': 30, 'd': 20}
for k in my_dict.keys():
my_dict[k] -= b
for s in string:
if s in my_dict.keys():
sum += my_dict[s]
print(sum)
Output
360
dont use reserved words as variable names.
In your code, you have used dict as a variable name which is a reserved keyword.
string = 'abdcabdcadcbacb'
b = 12
dictionary = {'a': 50, 'b': 40, 'c': 30, 'd': 20}
for i in dictionary.keys():
dictionary[i]-=b
print(dictionary)

Python get random value when using min() when there is more than one match

I have the following code:
dict = {'a': 1, 'b': 2, 'c': 5, 'd':1, 'e': 5, 'f': 1}
get_min = min(dict, key=dict.get)
As you can see here there is actually three min() matches "a", "d" and "f" with the value of 1.
This will return "a" 100% of the time as that is what min() is designed to do from what I am reading. However, I have a need where I would like to randomly get back "a", "d" or "f" instead of just "a".
Is there a way I can do this using min() or some other way (maybe lambda, I am not very good at it)? I thought this would be pretty simple but it turns out it is not :P. I can get this working with some for loops and creating lists but I was looking for the shortest way possible.
Your thoughts would be appreciated!
Thanks,
jAC
Here is one solution:
import random
dic = {'a': 1, 'b': 2, 'c': 5, 'd':1, 'e': 5, 'f': 1}
a = random.choice([k for k,v in dic.items() if v == min(dic.values())])
np.random.choice([k for k in dict.keys() if dict[key]==min(dict.values())])

How to calculate count of occurence of each value from a list column of Pandas efficiently?

I have a Pandas data frame, which looks like the following:
df =
col1
['a', 'b']
['d', 'c', 'a']
['b', 'f', 'a']
col1 is a list column, which contains strings. I want to calculate value counts of each element, which may occur in any of the lists in any row. Expected output is a dictionary, of counts of each value
Expected Output
df_dict = {'a': 3, 'b': 2, 'c': 1, 'd': 1, 'f': 1}
How to do this efficiently in 1 line preferably to make the code clean. Sorry, if it has been answered before.
With explode and value_counts:
df['col1'].explode().value_counts().to_dict()
Output:
{'a': 3, 'b': 2, 'd': 1, 'f': 1, 'c': 1}

Sort a dictionary a value

I know that this problem has been discussed, but none of the answers refer to a string as a key. I would like to sort a dictionary by a value - descending and ascending. Here are my sketches:
def ascending(d):
from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
return d
f={'a': 2, 'c': 1, 'f': 5, 'e': 4}
g={'s': 3, 'y': 1, 'r': 7, 'h': 4}
print(hj(f))
def descending(d):
from operator import itemgetter
sorted(d.items(), key=itemgetter(1), reverse=True)
return d
print(jh(g))
However, I get:
{'a': 2, 'c': 1, 'f': 5, 'e': 4}
{'h': 4, 'r': 7, 'y': 1, 's': 3}
What am I doing wrong? How can I improve the code?
OK, a little ask for explanation:
I have solved problem, using:
def ascending(d):
from operator import itemgetter
p=sorted(d.items(), key=itemgetter(1))
return p
f={'a': 2, 'c': 1, 'f': 5, 'e': 4}
g={'s': 3, 'y': 1, 'r': 7, 'h': 4}
print(hj(f))
def descending(d):
from operator import itemgetter
p=sorted(d.items(), key=itemgetter(1), reverse=True)
return p
print(jh(g))
How does sorted() works, if it doesn't affected d in 'return d'?
... but none of the answers refer to a string as a key.
That's not relevant.
What am I doing wrong?
There is a big difference between sort() and sorted(). The 1st is evaluated for side effects, and returns None. The 2nd leaves its argument untouched, and creates a brand new list in sorted order.
sorted(d.items(), key=itemgetter(1))
return d
You evaluated an expression (which did not change d), and then silently discarded the result. Then you returned the same old d.
You want to return sorted( ... ) instead.
How can I improve the code?
Thank you for asking, that's a terrific question! Do keep asking it of yourself.
PEP8 asks that you put import statements at top of source file, please.

Resources