Getting the highest key from python dictionary [duplicate] - python

This question already has answers here:
Using Python's max to return two equally large values
(6 answers)
Closed 5 years ago.
I have a python dictionary with values and I need to search the maximum key.
data={'A': 1,'C': 3, 'H': 1,'I': 1, 'B': 1,'J': 2,'S': 1, 'D': 3, 'N': 2}
I try max(data, key=data.get).This gives the C as an answer.But I'd like to get C & D as an answer,since both C and D are the highest number.
How this can be done in Python?

You can not do this with max alone, as max will only return a single element. Instead, first, get the maxvalue from data, then filter those keys that have the same value.
>>> data={'A': 1, 'T': 1, 'C': 3, 'H': 1, 'I': 1, 'B': 1, 'O': 1,'J': 2, 'Q': 1, 'S': 1, 'D': 3, 'N': 2}
>>> max_val = max(data.values())
>>> [key for key, val in data.items() if val == max_val]
['C', 'D']

Create a reverse map.
from collections import defaultdict
reverse_data_map = defaultdict(list)
for k, v in data.items():
reverse_data_map[v].append(k) # it becomes a list of keys that share a value
Then get the highest value, and use it to get your keys.
max_keys = reverse_data_map[max(reverse_data_map.keys())]
print max_keys # ['C', 'D']
As a robust function:
from collections import defaultdict
def get_all_max_keys(d):
reverse_map = defaultdict(list)
max_v = 0
for k, v in d.items():
max_v = max(max_v, v) # more efficient method than finding the max afterwards
reverse_map[v].append(k)
return reverse_map[max_v]
Calling the function:
data={
'A': 1, 'T': 1, 'C': 3, 'H': 1,
'I': 1, 'B': 1, 'O': 1, 'J': 2,
'Q': 1, 'S': 1, 'D': 3, 'N': 2,
}
print get_all_max_keys(data) # ['C', 'D']

Something like this?
max_keys = [ k for k, val in data.items() if val == max(data.values()) ]

Related

convert flatten dict to nested dict

I use this function to convert nested dict to flatten dict:
make_flatten_dict = lambda d, sep: pd.json_normalize(d, sep=sep).to_dict(orient='records')[0]
input:
d = {'a': 1,
'c': {'a': '#a_val', 'b': {'x': '#x_value', 'y' : '#y'}},
'd': [1, '#d_i1', 3]}
output:
{'a': 1, 'd': [1, '#d_i1', 3], 'c.a': '#a_val', 'c.b.x': '#x_value', 'c.b.y': '#y'}
How I can build input from the output?
For each multi-key you need to build the tree, add a {} for each one except the last, then use the last one to assign the value
value = {'a': 1, 'd': [1, '#d_i1', 3], 'c.a': '#a_val', 'c.b.x': '#x_value', 'c.b.y': '#y'}
result = {}
for k, v in value.items():
tmp = result
*keys, last = k.split(".")
for key in keys:
tmp = tmp.setdefault(key, {})
tmp[last] = v
print(result)
# {'a': 1, 'd': [1, '#d_i1', 3], 'c': {'a': '#a_val', 'b': {'x': '#x_value', 'y': '#y'}}}

How to create new dictionary from string?

I have a string: my_str = "abra cadabra"
I need to create a new dictionary , the keys in the dictionary are the letters in my_str and the value should be the amount of every letter.
For example:
my_str = "abra cadabra"
output >>
{'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}
What i got is - {'a': 5, 'b': 5, 'r': 5, 'c': 5, 'd': 5}
Try this:
my_str = "abra cadabra"
my_set = set(my_str)
my_set.discard(" ")
my_dict = {}
for key in my_set:
my_dict[key] = my_str.count(key)
print(my_dict)
collections.Counter could be used for this.
Example:
from collections import Counter
my_str = "abra cadabra"
my_str = my_str.replace(" ", "")
c = Counter(list(my_str))
print('{}\n{}\n{}'.format(c, c.keys(), c.values()))
output:
Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
dict_keys(['a', 'b', 'r', 'c', 'd'])
dict_values([5, 2, 2, 1, 1])
You can iterate through the keys and values just like you would a normal dict.

How to make all the dictionary values unique in python?

I want a solution to make all the keys of a dictionary have a unique value, and to do that delete the values as minimum as possible to have each value unique. For example:
my_dict = {'c': 3, 'e': 3, 'a': 2, 'f': 2, 'd': 2}
for the above dictionary I need to sub 2 from 'f' and 3 of times from 'e' and 1 time from 'd'. and result would be 6 which means {'c':3, 'a':2, 'd':1}. Removing keys is not a problem.
note we could remove 'c' rather than 'e' or 'a' rather than f'' it's not important which key should be decreed or be removed , what matters is having unique values
This is what I have tried:
for k, v in my_dict.items():
c = 0
while len(my_dict.values()) > len(set(my_dict.values())):
my_dict[k] = my_dict[k] -1
c += 1
It is not the result you were expecting, but it meets the requirements.
my_dict = {'c': 3, 'e': 3, 'a': 2, 'f': 2, 'd': 2}
to_remove = []
result = {}
for key, value in my_dict.items():
while value > 0:
if value not in to_remove:
to_remove.append(value)
result[key] = value
break
else:
value -= 1
result
Simple approach:
my_dict = {'c': 3, 'e': 3, 'a': 2, 'f': 2, 'd': 2}
rd = {v: k for k, v in my_dict.items()}
my_dict = {v: k for k, v in rd.items()}
print(my_dict)

How to combine two list containing dictionary with similar keys?

Assuming that there are two python list with the same structure like this:
var1 = [{'a':1,'b':2},{'c':2,'d':5,'h':4},{'c':2,'d':5,'e':4}]
var2 = [{'a':3,'b':2},{'c':1,'d':5,'h':4},{'c':5,'d':5,'e':4}]
In my case, i need to combine both of those list, so i'll get this value :
result = [{'a':4,'b':4},{'c':3,'d':10,'h':8},{'c':7,'d':10,'e':8}]
How can i do that?
zip-based one-liner comprehension:
result = [{k: d1[k]+d2[k] for k in d1} for d1, d2 in zip(var1, var2)]
This assumes that two dicts at the same index always have identical key sets.
Use list comprehensions to put the code in one line,
result = [{key : d1.get(key, 0)+d2.get(key, 0)
for key in set(d1.keys()) | set(d2.keys())} # union two sets
for d1, d2 in zip(var1, var2)]
print(result)
[{'a': 4, 'b': 4}, {'h': 8, 'c': 3, 'd': 10}, {'c': 7, 'e': 8, 'd': 10}]
This code takes into consideration the case that two dictionaries may not have the same keys.
var1 = [{'a':1,'b':2},{'c':2,'d':5,'h':4},{'c':2,'d':5,'e':4}]
var2 = [{'a':3,'b':2},{'c':1,'d':5,'h':4},{'c':5,'d':5,'e':4}]
res = []
for i in range(len(var1)):
dic = {}
dic1, dic2 = var1[i], var2[i]
for key, val in dic1.items(): // dic1.iteritems() in python 2.
dic[key] = dic1[key] + dic2[key]
res.append(dic)
>>>print(res)
[{'a': 4, 'b': 4}, {'c': 3, 'd': 10, 'h': 8}, {'c': 7, 'd': 10, 'e': 8}]
var1 = [{'a': 1, 'b': 2}, {'c': 2, 'd': 5, 'h': 4}, {'c': 2, 'd': 5, 'e': 4}]
var2 = [{'a': 3, 'b': 2}, {'c': 1, 'd': 5, 'h': 4}, {'c': 5, 'd': 5, 'e': 4}]
ret = []
for i, ele in enumerate(var1):
d = {}
for k, v in ele.items():
value = v
value += var2[i][k]
d[k] = value
ret.append(d)
print(ret)
For the sake of completeness, another zip-based one-liner that will work even if the dicts are uneven in the both lists:
result = [{k: d1.get(k, 0) + d2.get(k, 0) for k in set(d1) | set(d2)} for d1, d2 in zip(var1, var2)]
Would something like this help?
ar1 = [{'a':1,'b':2},{'c':2,'d':5,'h':4},{'c':2,'d':5,'e':4}]
var2 = [{'a':3,'b':2},{'c':1,'d':5,'h':4},{'c':5,'d':5,'e':4}]
combined_var = zip(var1, var2)
new_d = {}
list_new_ds = []
for i, j in combined_var:
new_d = {}
for key in i and j:
new_d[key] = i[key] + j[key]
list_new_ds.append(new_d)
list_new_ds = [{'a': 4, 'b': 4}, {'h': 8, 'c': 3, 'd': 10}, {'c': 7, 'e': 8, 'd': 10}]
To explain, the zip function merges the lists as a list of tuples. I then unpack the tuples and iterate through the keys in each dictionary and add the values for the same keys together using a new dictionary to store them. I then append the value to a list, and then re-initialise the temporary dictionary to empty before looking at the next tuple in the zipped list.
The order is different due to dictionary behaviour I believe.
I am a novice, so would appreciate any critiques of my answer!

Getting keys with max value from dictionary with more than one keys with same value

How to get keys with maximum values when there are more than one keys with same value.
Example: d = 'a': 1, 'c': 4, 'b': 99, 'e': 4, 'f': 99}, I need to return 'b','f'
>>> d = {'a': 1, 'c': 4, 'b': 99, 'e': 4, 'f': 99}
>>> maxval = max(d.values())
>>> [k for k in d if d[k]==maxval]
['b', 'f']
Damn :P Got beaten by a minute. Cheers m8.
maxValue = max(d.values())
print [key for key in d.keys() if d[key]==maxValue]

Categories