Find n largest values from dictionary - python

I am working in Python project and I have a problem seem as what I explain below but with other data.
For example, if I have this dict:
fruitsCount= {"apple": 24, "orange": 20, "banana":18, "grape":13, "kiwi": 13}
how can I return the keys with maximum values ? what if I want to return three largest ?
I used heapq.nlargest(3, fruitCount.values) but I don't know how I return them with their keys
Note: fruitsCount is a dict returned after using Counter() from another dict.
Output: should be same fruitsCount dictionary with n largest fruitsCount.values

You need to use heapq.nlargest() on the items, and use the key argument to tell it to take the value from that pair:
heapq.nlargest(3, fruitCount.items(), key=lambda i: i[1])
This returns the 3 largest (key, value) pairs.
Or you could just use the collections.Counter() class, which has a most_common() method that does this for you:
Counter(fruitCount).most_common(3)

Having never used the heapq module, I prefer this module-free approach:
sorted( fruitsCount.items(), key=lambda pair: pair[1], reverse=True )[:3]
Smaller, but less clear:
sorted( fruitsCount.items(), key=lambda pair: -pair[1] )[:3]

You can try this one. Your answer will be apple, orange, banana.
heapq.nlargest(3, d, key=fruitsCount.get)
Time complexity in this approach will be nlog(t). N is the number of elements in the dictionary and t is the number of elements you want. In the above case, t is 3.

New to python not very sure about the shortcut, but here is my answer:
from heapq import nlargest
fruitsCount= {"apple": 24, "orange": 20, "banana":18, "grape":13, "kiwi": 13}
Reverse the key value pairs so that sorting is done wrt values:
fruitsCount = {j:i for i,j in fruitsCount.items()}
Find the largest 3 items in a separate dictionary:
x = dict(nlargest(3,fruitsCount.items()))
Reverse the dictionary back to original form:
x = {z:y for y,z in x.items()}
print(x)

Related

Fastest way to get key with most items in a dictionary?

I am trying to find the fastest way to get the dictionary key with the most items. The two methods I have tried so far are:
def get_key_with_most_items(d):
maxcount = max(len(v) for v in d.values())
return [k for k, v in d.items() if len(v) == maxcount][0]
and
def sort_by_values_len(dict):
dict_len = {key: len(value) for key, value in dict.items()}
import operator
sorted_key_list = sorted(dict_len.items(), key=operator.itemgetter(1), reverse=True)
sorted_dict = [{item[0]: dict[item [0]]} for item in sorted_key_list]
return sorted_dict
The first method return the key with the biggest number of items, while the second returns the whole dictionary as a list. In my case I only need the key, just to be clear. After comparing these methods in this manner:
start_time = time.time()
for i in range(1000000):
get_key_with_most_items(my_dict) # sort_by_values_len(my_dict)
print("Time", (time.time() - start_time))
I have come to the conclusion that the get_key_with_most_items method is faster by almost 50%, with times 15.68s and 8.06s respectively. Could anyone recommend (if possible) something even faster?
The solution is extremely simple:
max(d, key=lambda x: len(d[x]))
Explanation:
dictionaries, when iterated, are just a set of keys. max(some_dictionary) will take maximum of keys
max optionally accepts a comparison function (key). To compare dictionary keys by the amount of items, the built-in len does just the job.
Use d.items() to get a sequence of the keys and values. Then get the max of this from the length of the values.
def get_key_with_most_items(d):
maxitem = max(d.items(), key = lambda item: len(item[1]))
return maxitem[0]
for the max function:
max(d, key=lambda k: len(d[k]))
If you want the dict to be ordered, then use OrderedDict. I think technically your code will still work with regular dict, but that's a technicality based on the current implementation of Pythons dict - In the past regular dict would not have reliable order, and in the future it may not.
You could do this for example as a one liner to turn your dict into an ordered dict by value length:
from collections import OrderedDict
ordered_dict = OrderedDict(sorted(d.items(), key=lambda t: len(t[1])))

How to give the max item of a dictionary given a value somewhere in an array in the value?

In python, say I have a dictionary
{1:[1,333], 2:[5,22], 3:[8:0]}
I want to return the max item in the dictionary by the second item in the value array, so in this case, 333 beats all the rest numbers in the same place, I wish the function can return
(1,[1,33])
Is there any neat way to implement this using max() with key or something else?
>>> d = {1:[1,333], 2:[5,22], 3:[8, 0]}
>>> max(d.items(), key=lambda e: e[1][1])
(1, [1, 333])
You can achieve this using the key argument to max(), i.e.:
d = {1:[1,333], 2:[5,22], 3:[8,0]}
# Use d[k][1] so that max is based on the second
# item in each list
max_key = max(d, key=lambda k: d[k][1])
print((max_key, d[max_key]))
(1, [1, 333])

Python: OrderedDictionary sorting based on length of key's value

I have an object like this:
t = {'rand_key_1': ['x'], 'rand_key_2': [13,23], 'rand_key_3': [(1)], 'rk5': [1,100,3,4,3,3]}
a dictionary with random keys (string and/or int) which ALL have a list as a value, with varying sizes.
I want to turn this dictionary into an OrderedDict which is ordered depending on the Length of the list of the dictionary items. So after ordering I want to get:
t_ordered = {'rk5': ..., 'rand_key_2': .., 'rand_key_1': .., 'rand_key_3': ..}
(if two or more items have same value, their order do not really matter.
I tried this but I am failing:
OrderedDict(sorted(d, key=lambda t: len(t[1])))
I am not experiences so excuse me if what I try is uber stupid.
What can I do?
Thank you.
You were actually very close with the sorting function you passed to sorted. The thing to note is that sorted will return an interable of the dictionaries keys in order. So if we fix your function to index the dictionary with each key:
>>> sorted(t, key=lambda k: len(t[k]))
['rand_key_3', 'rand_key_1', 'rand_key_2', 'rk5']
You can also specify that the keys are returned in reverse order and iterating directly over these keys:
>>> for sorted_key in sorted(t, key=lambda k: len(t[k]), reverse=True):
... print sorted_key, t[sorted_key]
rk5 [1, 100, 3, 4, 3, 3]
rand_key_2 [13, 23]
rand_key_3 [1]
rand_key_1 ['x']
Usually you wouldn't need to create an OrderedDict, as you would just iterate over a new sorted list using the latest dictionary data.
Using simple dictionary sorting first and then using OrderedDict():
>>> from collections import OrderedDict as od
>>> k=sorted(t, key=lambda x:len(t[x]), reverse=True)
>>> k
['rk5', 'rand_key_2', 'rand_key_3', 'rand_key_1']
>>> od((x, t[x]) for x in k)
OrderedDict([('rk5', [1, 100, 3, 4, 3, 3]), ('rand_key_2', [13, 23]), ('rand_key_3', [1]), ('rand_key_1', ['x'])])
Since an ordered dictionary remembers its insertion order, so you can do this:
OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict in Python is a collection that remembers the order in which items were inserted. Ordered in this context does not mean sorted.
If all you need is to get all the items in sorted order you can do something like this:
for key, value in sorted(t, key = lambda x: -len(x[0])):
# do something with key and value
However, you are still using an unsorted data structure - just iterating over it in sorted order. This still does not support operations like looking up the k-th element, or the successor or predecessor of an element in the dict.

how to sort a dictionary using values and also be able to access keys

dic = {'Tea': 35, 'Coffee': 35, 'Chocolate': 10}
I want to sort this dictionary by values in descending order, but how can I access keys too?
Sample Code:
for x in sorted(dic.values()):
print(key, dic[key])
I'd also like the output to be sorted alphabetically by key when the values are equal.
Expected Output:
Coffee 35
Tea 35
Chocolate 10
What you want is the dict.items() method, which provides (key, value) tuples.
To sort by the value, you then use a key method, in this case, an operator.itemgetter() to take the second value from the tuple for sorting, then set the reverse attribute to get them in the order you want.
>>> from operator import itemgetter
>>> dic={'Tea': 35, 'Coffee': 35, 'Chocolate': 10}
>>> for key, value in sorted(dic.items(), key=itemgetter(1), reverse=True):
... print(key, value)
...
Tea 35
Coffee 35
Chocolate 10
Edit: If you want to sort by key as a secondary sort, we can simply pass a tuple of values, and Python will sort on the first value, then the second, etc... The only issue is using reverse will mean we get them in the wrong order. As a hack, we simply use the negative version of the value to sort without reverse:
>>> for key, value in sorted(dic.items(), key=lambda x: (-x[1], x[0])):
... print(key, value)
...
Coffee 35
Tea 35
Chocolate 10
One option:
for key in sorted(dic, key=dic.get, reverse=True):
print(key,dic[key])
This sorts the keys of the dictionary, but uses dic.get as key function, thereby effectively sorting by value. Your example output indicates you want to sort in descending order, so I included reverse=True.
Edit: If your dictionary values are actually counts, you might consider using a collections.Counter instead of a dicitonary. That class has a method most_common() which returns the items in the desired order.
The other answers which suggest dict.items() are partially right. But as you want to include the key in the sorting process (if I understand you correct), you want to reverse the items (which are essentially a tuple (key, value)). So use
data={'Tea': 35, 'Coffee': 35, 'Chocolate': 10}
for item in sorted(dic.items(), key=lambda it: (-it[1], it[0])):
print item
The key parameter gives a function which is used for sorting the items. It converts the items into a key which is then really used for sorting.
In your case, you want a mixed descending / ascending sort, so that the items given here are first turned into
(-35, 'Coffee')
(-35, 'Tea')
(-10, 'Chocolate')
and printed in that order. (The replacement process just happens for sorting purposes, the items actually returned are the original ones.)

top -10 unique dictionary keys to be found on the basis of value

Need to find out the top-10 dictionary key's on the basis of value.... value is a tuple of two fields..
{ Key : (value1, value2) }
So first, we have to find the list of key's on the basis of top 10 value1's and then we have to find the list of key's on the basis of top 10 value2's.
And then we have to find the set of list1 and list2, and return the list...
How can we do this in pythonic way...
Or I should i write the complete logic, to do this stuff...
I wrote one solution:
where the dictionary is a key:value pair.....
dict(sorted(dict_mapping.iteritems(), key=lambda dict_mapping:dict_mapping[1]) [0:10]).keys()
Please help..
If the dictionary values are tuples, python's sorted() will do a lexicographical sorting. This means, value1 will be used to sort and value2 will be used for tie-breaking.
sorted(a.keys(), key=a.get)[:10]
This should result in the top 10 keys that are sorted by values instead of keys in the dictionary.
sorted(data.keys(), key=lambda x: data[x][1])[:10]
data = {'key1': ('value1', 'value2'), 'key2': ('value3', 'value4')}
tmp = [sorted(data.keys(), key=lambda x: data[x][i])[:10] for i in (0, 1)]
result = set(tmp[0]+tmp[1])

Categories

Resources