If I have a Python dictionary, how do I get the key to the entry which contains the nth minimum value?
Given the input:
input = {'Apple':1, 'Banana':3, 'Orange':9,
'Watermelon':5, 'Mango': 4, 'Peach': 4,'Blueberry':10}
def return_smallest_key(input, n):
if n = 3
It should return 'Mango', 'Peach'
Also, if someone could introduce two different solutions,
Solution one: n = 6, return Blueberry (since Mango and Peach both equal to 4, we count them in the rank as 1,2,3,3,4,5,6)
Solution two: n = 6 return Orange (Count Mango and Peach in the rank as 1,2,3,3,5,6,7)
CodePudding user response:
Solution one:
def return_smallest_key(dictionary, n):
ser = pd.Series(dictionary).rank(method='dense')
return list(ser[ser==float(n)].index)
return_smallest_key(input, 6)
Solution two:
def return_smallest_key(dictionary, n):
ser = pd.Series(dictionary).rank(method='first')
return list(ser[ser==float(n)].index)
return_smallest_key(input, 6)
CodePudding user response:
Approach
- Create sorted key, value pairs of dictionary items
- Group pairs by value
- Find rank by counting items from lowest value group until we get the desired rank
Note: input should never be used as a global variable names since it conflicts with builtin function
Code
from itertools import groupby
# input values (shouldn't use input as variable name in Python)
data = {'Apple':1,
'Banana':3,
'Orange':9,
'Watermelon':5,
'Mango': 4,
'Peach': 4,
'Blueberry':10}
def solution_one(d, rank):
' Sort dictionary value, creating a list of tuples of key, value pairs '
values = sorted(d.items(), key = lambda kv: kv[1])
# Group tuples by value
# Determine rank by counting pairs until we reach desired rank
count = 0
for k, v in groupby(values, key = lambda kv: kv[1]):
v = list(v)
if count 1 == rank:
return [x[0] for x in v] # List of values at this rank
elif count > rank:
return # Will not have any values that match rank
count = 1 # update count of tuples encountered
def solution_two(d, rank):
' Sort dictionary value, creating a list of tuples of key, value pairs '
values = sorted(d.items(), key = lambda kv: kv[1])
# Group tuples by value
# Determine rank by counting pairs until we reach desired rank
count = 0
for k, v in groupby(values, key = lambda kv: kv[1]):
v = list(v)
if count 1 == rank:
return [x[0] for x in v] # List of values at this rank
elif count > rank:
return # Will not have any values that match rank
count = len(v) # update count of tuples encountered
Test
Test solutions 1 & 2 by displaying ranks 1 through 8
print('# Ranks for Solution 1')
for r in range(1, 9):
print(r, solution_one(data, r))
print()
print('# Ranks for Solution 2')
for r in range(1, 9):
print(r, solution_two(data, r))
Output
# Ranks for Solution 1
1 ['Apple']
2 ['Banana']
3 ['Mango', 'Peach']
4 ['Watermelon']
5 ['Orange']
6 ['Blueberry']
7 None
8 None
# Ranks for Solution 2
1 ['Apple']
2 ['Banana']
3 ['Mango', 'Peach']
4 None
5 ['Watermelon']
6 ['Orange']
7 ['Blueberry']
8 None