How to make all the dictionary values unique in python? - 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)

Related

Getting the highest key from python dictionary [duplicate]

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()) ]

How to "sort" a dictionary by number of occurrences of a key?

I have a dictionary of values that gives the number of occurrences of a value in a list. How can I return a new dictionary that divides the former dictionary into separate dictionaries based on the value?
In other words, I want to sort this dictionary:
>>> a = {'A':2, 'B':3, 'C':4, 'D':2, 'E':3}
to this one.
b = {2: {'A', 'D'}, 3: {'B', 'E'}, 4: {'C'}}
How do I approach the problem?
from collections import defaultdict
a = {'A': 2, 'B': 3, 'C': 4, 'D': 2, 'E': 3}
b = defaultdict(set)
for k, v in a.items():
b[v].add(k)
This is what you'll get:
defaultdict(<class 'set'>, {2: {'D', 'A'}, 3: {'B', 'E'}, 4: {'C'}})
You can convert b to a normal dict afterwards with b = dict(b).
if you are a python beginner like me, you probably wanna try this
a = {'A': 2 , 'B': 3 , 'C' : 4 , 'D' : 2, 'E' : 3}
b = {}
for key in a:
lst = []
new_key = a[key]
if new_key not in b:
lst.append(key)
b[new_key] = lst
else:
b[new_key].append(key)
print(b)
It uses the mutable property of python dictionary to achieve the result you want.

Extracting key from the nested dictionary [duplicate]

So I have this block of code
dictionary = {
'key1': {'a': 1, 'b': 2, 'c': 10},
'key2': {'d': 1, 'e': 1, 'c': 11},
'key3': {'d': 2, 'b': 1, 'g': 12}}
and
list1 = (a,b,c)
What I want to do is run a loop that finds the maximums of all the items in the list and returns the key. So for example, the maximum of 'c' would return 'key2', the maximum of 'b' would return 'key1', etc.
So far I have
for value in list1:
m = max(dictionary, key=lambda v: dictionary[v][value])
print(m + "\n")
But this only works if the same subkey exists in all keys in the dictionary. Any ideas on what to do?
Use float('-inf') when the key is missing:
m = max(dictionary, key=lambda v: dictionary[v].get(value, float('-inf')))
Negative infinity is guaranteed to be smaller than any existing value in the dictionaries, ensuring that nested dictionaries with the specific key missing are ignored.
Demo:
>>> dictionary = {
... 'key1': {'a': 1, 'b': 2, 'c': 10},
... 'key2': {'d': 1, 'e': 1, 'c': 11},
... 'key3': {'d': 2, 'b': 1, 'g': 12}}
>>> list1 = ('a', 'b', 'c')
>>> for value in list1:
... print(value, max(dictionary, key=lambda v: dictionary[v].get(value, float('-inf'))))
...
a key1
b key1
c key2
However, it'll be more efficient if you looped over all your dictionary values just once instead:
maximi = dict.fromkeys(list1, (None, float('-inf')))
for key, nested in dictionary.items():
for k in nested.keys() & maximi: # intersection of keys
if maximi[k][0] is None or dictionary[maximi[k][0]][k] < nested[k]:
maximi[k] = (key, nested[k])
for value in list1:
print(value, maximi[value][0])
That's presuming you are using Python 3; in Python 2, replace .items() with .iteritems() and .keys() with .viewkeys().
Demo:
>>> maximi = dict.fromkeys(list1, (None, float('-inf')))
>>> for key, nested in dictionary.items():
... for k in nested.keys() & maximi: # intersection of keys
... if maximi[k][0] is None or dictionary[maximi[k][0]][k] < nested[k]:
... maximi[k] = (key, nested[k])
...
>>> maximi
{'a': ('key1', 1), 'b': ('key1', 2), 'c': ('key2', 11)}
>>> for value in list1:
... print(value, maximi[value][0])
...
a key1
b key1
c key2

Find Maximum Value in Nested Dictionary and return Key

So I have this block of code
dictionary = {
'key1': {'a': 1, 'b': 2, 'c': 10},
'key2': {'d': 1, 'e': 1, 'c': 11},
'key3': {'d': 2, 'b': 1, 'g': 12}}
and
list1 = (a,b,c)
What I want to do is run a loop that finds the maximums of all the items in the list and returns the key. So for example, the maximum of 'c' would return 'key2', the maximum of 'b' would return 'key1', etc.
So far I have
for value in list1:
m = max(dictionary, key=lambda v: dictionary[v][value])
print(m + "\n")
But this only works if the same subkey exists in all keys in the dictionary. Any ideas on what to do?
Use float('-inf') when the key is missing:
m = max(dictionary, key=lambda v: dictionary[v].get(value, float('-inf')))
Negative infinity is guaranteed to be smaller than any existing value in the dictionaries, ensuring that nested dictionaries with the specific key missing are ignored.
Demo:
>>> dictionary = {
... 'key1': {'a': 1, 'b': 2, 'c': 10},
... 'key2': {'d': 1, 'e': 1, 'c': 11},
... 'key3': {'d': 2, 'b': 1, 'g': 12}}
>>> list1 = ('a', 'b', 'c')
>>> for value in list1:
... print(value, max(dictionary, key=lambda v: dictionary[v].get(value, float('-inf'))))
...
a key1
b key1
c key2
However, it'll be more efficient if you looped over all your dictionary values just once instead:
maximi = dict.fromkeys(list1, (None, float('-inf')))
for key, nested in dictionary.items():
for k in nested.keys() & maximi: # intersection of keys
if maximi[k][0] is None or dictionary[maximi[k][0]][k] < nested[k]:
maximi[k] = (key, nested[k])
for value in list1:
print(value, maximi[value][0])
That's presuming you are using Python 3; in Python 2, replace .items() with .iteritems() and .keys() with .viewkeys().
Demo:
>>> maximi = dict.fromkeys(list1, (None, float('-inf')))
>>> for key, nested in dictionary.items():
... for k in nested.keys() & maximi: # intersection of keys
... if maximi[k][0] is None or dictionary[maximi[k][0]][k] < nested[k]:
... maximi[k] = (key, nested[k])
...
>>> maximi
{'a': ('key1', 1), 'b': ('key1', 2), 'c': ('key2', 11)}
>>> for value in list1:
... print(value, maximi[value][0])
...
a key1
b key1
c key2

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