I have a dictionary like:
data = {'sachin': {'score': 15000, 'out': 100},
'Dhoni': {'score': 8000, out: 80},
'Shewag': {'score': 12000, 'out': 150}}
I want to get two players whose score are in top.
So I tried like: key = (key for key,value in dd.items() if value['score'] > 'value').next()
Winded here with no success.
Tried using link:top n keys with highest values in dictionary with tuples as keys
As newbie to Python couldn't get around the perfect solution.
Can someone share some idea on this!!!
Output like:
{'sachin':{'score':15000,'out':100},'Shewag':{'score':12000,'out':150}}
Note: Should be top n player, just for example I need top two but It can be changed later stage.
Sorting works:
>>> dict(sorted(data.items(), key=lambda x: x[1]['score'], reverse=True)[:2])
{'Shewag': {'out': 150, 'score': 12000},
'sachin': {'out': 100, 'score': 15000}}
You sort the items:
>>> sorted(data.items())
[('Dhoni', {'out': 80, 'score': 8000}),
('Shewag', {'out': 150, 'score': 12000}),
('sachin', {'out': 100, 'score': 15000})]
This sorts by the names in alphabetical order.
Using a key
function defined with lambda
sorts by score
:
sorted(data.items(), key=lambda x: x[1]['score'])
[('Dhoni', {'out': 80, 'score': 8000}),
('Shewag', {'out': 150, 'score': 12000}),
('sachin', {'out': 100, 'score': 15000})]
Use reverse
to get the largest one first:
sorted(data.items(), key=lambda x: x[1]['score'], reverse=True)
[('sachin', {'out': 100, 'score': 15000}),
('Shewag', {'out': 150, 'score': 12000}),
('Dhoni', {'out': 80, 'score': 8000})]
Finally, take only the two first items with slicing and convert the list of tuples into a dictionary with dict
:
>>> dict(sorted(data.items(), key=lambda x: x[1]['score'], reverse=True)[:2])
{'Shewag': {'out': 150, 'score': 12000},
'sachin': {'out': 100, 'score': 15000}}
Since a dictionary has no order, you only know that you have two players with top most scores. There is no notion who is first or second. If need this, you can either keep the list of tuples or convert into an OrderedDict
to preserve the order:
>>> from collections import OrderedDict
>>> OrderedDict(sorted(data.items(), key=lambda x: x[1]['score'], reverse=True)[:2])
OrderedDict([('sachin', {'out': 100, 'score': 15000}),
('Shewag', {'out': 150, 'score': 12000})])
To make it bit more reusable, you can write a function:
from collections import OrderedDict
def get_top_players(data, n=2, order=False):
"""Get top n players by score.
Returns a dictionary or an `OrderedDict` if `order` is true.
"""
top = sorted(data.items(), key=lambda x: x[1]['score'], reverse=True)[:n]
if order:
return OrderedDict(top)
return dict(top)
Now you can use it just with your data:
>>> get_top_players(data)
{'Shewag': {'out': 150, 'score': 12000},
'sachin': {'out': 100, 'score': 15000}}
or set a different number of top players:
>>> get_top_players(data, n=3)
{'Dhoni': {'out': 80, 'score': 8000},
'Shewag': {'out': 150, 'score': 12000},
'sachin': {'out': 100, 'score': 15000}}
or get them in order:
>>> get_top_players(data, order=True)
OrderedDict([('sachin', {'out': 100, 'score': 15000}),
('Shewag', {'out': 150, 'score': 12000})])
Your link is right. You must modify it to use it for your case.
The method is:
You can do it with the library heapq
>>> import heapq
>>> heapq.nlargest(2, data.keys(), key=lambda k: data[k]['score'])
['sachin', 'Shewag']
Now you can create a new OrderedDict
to store your dict
import heapq
from collections import OderedDict
player_names = heapq.nlargest(2, data.keys(), key=lambda k: data[k]['score'])
ret = OrderedDict((x, data[x]) for x in player_names)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With