Issue
I have a list of dictionaries which contains contains floats. My goal is to rank these objects with considering the occurence the duplicates.
Example:
If the highest value is 19.93
and it occurs three times in the raw list, we will have three {"rank":1}
's, and as we already have 3 ranked items, the item with 19.07
value will have {"rank":4}
as there are three above ranked objects. (This is the logic how european soccer score rankings are calculated. I want to achieve the same)
{'value': {'total': 19.93}, 'rank': 1}
{'value': {'total': 19.93}, 'rank': 1}
{'value': {'total': 19.93}, 'rank': 1}
{'value': {'total': 19.07}, 'rank': 4}
{'value': {'total': 18.24}, 'rank': 5}
{'value': {'total': 18.24}, 'rank': 5}
{'value': {'total': 18.24}, 'rank': 5}
{'value': {'total': 17.15}, 'rank': 8}
{'value': {'total': 16.8}, 'rank': 9}
{'value': {'total': 16.8}, 'rank': 9}
{'value': {'total': 16.8}, 'rank': 9}
But instead of the above, my code gives me:
{'value': {'total': 19.93}, 'rank': 1}
{'value': {'total': 19.93}, 'rank': 1}
{'value': {'total': 19.93}, 'rank': 1}
{'value': {'total': 18.24}, 'rank': 3}
{'value': {'total': 18.24}, 'rank': 3}
{'value': {'total': 18.24}, 'rank': 3}
{'value': {'total': 19.07}, 'rank': 4}
{'value': {'total': 17.15}, 'rank': 5}
{'value': {'total': 16.8}, 'rank': 6}
{'value': {'total': 16.8}, 'rank': 6}
{'value': {'total': 16.8}, 'rank': 6}
What I basically do is creating a unique list from the values, track the occurrence of the previous objects and add it to the current rank
. I would really appreciate if somebody could show me what do I wrong as I feel I am really close.
#########################
# actual code
import random
def rank_lista(ordered_list):
vals = []
# add all values into a list
for list_item in ordered_list:
try:
vals.append(list_item['value']['total'])
except Exception as e:
print (e)
unique_values = sorted(list(set(vals)))
sorted_list = []
for ooo in reversed(list(unique_values)):
sorted_list.append(ooo)
unique_values = []
unique_values = sorted_list
print ('sorted unique values:', unique_values)
for ordered_list_item in ordered_list:
try:
val = ordered_list_item['value']['total']
if unique_values.index(val) == 0:
ordered_list_item['rank'] = unique_values.index(val)+1
elif unique_values.index(val) == 1:
previous_value_index = 0
previous_value_count = vals.count(unique_values[previous_value_index])
ordered_list_item['rank'] = 1 + previous_value_count
else:
previous_value_index = unique_values.index(val)-1
previous_value_count = vals.count(unique_values[previous_value_index])
ordered_list_item['rank'] = (previous_value_index + 1) + previous_value_count
except Exception as e:
print (e,2)
return ordered_list
def create_random_list():
unique_rounded_floats = list(set(round(random.uniform(1, 20), 2) for _ in range(9)))
floats_with_duplicates = [item for sublist in [[float_] * 3 for float_ in unique_rounded_floats] for item in sublist]
other_floats = [round(random.uniform(1, 20), 2) for _ in range(11)]
result_array = floats_with_duplicates + other_floats
arr = []
for r in result_array:
obj = {}
obj['value'] = {'total':r}
arr.append(obj)
return arr
random_list = create_random_list()
print (random_list)
result_list = sorted(rank_lista(random_list), key=lambda d: float(d['rank']), reverse = False)
for res in result_list:
print (res)
Solution
You can use a simple loop, keeping track of the previous value and incrementing the rank if the value changes from an enumerate
:
prev = None # this must be different from a number
# for each dictionary in descending order of values
for i, d in enumerate(sorted(random_list,
key=lambda x: x['value']['total'],
reverse=True), start=1):
# if the value changes, update the rank
if d['value']['total'] != prev:
rank = i
# assign the rank
d['value']['rank'] = rank
prev = d['value']['total']
Output:
[{'value': {'total': 19.93}, 'rank': 1},
{'value': {'total': 19.93}, 'rank': 1},
{'value': {'total': 19.93}, 'rank': 1},
{'value': {'total': 19.07}, 'rank': 4},
{'value': {'total': 18.24}, 'rank': 5},
{'value': {'total': 18.24}, 'rank': 5},
{'value': {'total': 18.24}, 'rank': 5},
{'value': {'total': 17.15}, 'rank': 8},
{'value': {'total': 16.8}, 'rank': 9},
{'value': {'total': 16.8}, 'rank': 9},
{'value': {'total': 16.8}, 'rank': 9}]
Answered By - mozway
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.