Python Forum

Full Version: Input validation for nested dict and sorting list of tuples
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi everyone,
First of all I want to say that I really appreciate this forum and Ive learned alot since I joined!
Im trying to write a func that icludes input validation for a nested dict, converting it to a list of tupples and then arrange it by order.

this is the nested dict:
{'Afghanistan': {'Gold': 0, 'Silver': 0, 'Bronze': 2, 'Total': 2}, 'Albania': {'Gold': 0, 'Silver': 0, 'Bronze': 0, 'Total': 0}, 'Algeria': {'Gold': 5, 'Silver': 4, 'Bronze': 8, 'Total': 17}}
this is the output I want to get in the end:
Output:
[(' 1 , ‘Algeria’, 17), (2, 'Afghanistan, 2), (3, ‘Albania, 0)[
Thats my try:
def rank_countries(dict1):
    if isinstance(dict1, dict):
         for i in dict1:
             if isinstance(dict1[i], dict):
                 new_list = [(k, v['Total']) for k, v in dict1.items()]
                 new_list=sorted(new_list, key= lambda tup: tup[1], reverse= True)   
                 return new_list
                     
                        
    else:
       return 'Input must be a nested dictionary.'
which give me this output:
Output:
[(' ‘Algeria’, 17), ('Afghanistan, 2), ( ‘Albania, 0)[
So I get the ordeer I want but I dont know how to add the digits in start of each tuple that declair the rank of the country... also Im not sure in my input validation for the nested dicionary is good or its only right for the first dictionary..

Thanks for any kind of help!
You could use enumerate to add the digits to your result.
result = [('Algeria', 17), ('Afghanistan', 2), ('Albania', 0)]
print([(index, value) for index, value in enumerate(result, 1)])
Output:
[(1, ('Algeria', 17)), (2, ('Afghanistan', 2)), (3, ('Albania', 0))]

I just realised the index digits should be in the same tuple as the rest of the items.
result = [('Algeria', 17), ('Afghanistan', 2), ('Albania', 0)]
print([(index, *value) for index, value in enumerate(result, 1)])
Output:
[(1, 'Algeria', 17), (2, 'Afghanistan', 2), (3, 'Albania', 0)]
Here's another way to go about it.

tester = {'Afghanistan': {'Gold': 0, 'Silver': 0, 'Bronze': 2, 'Total': 2}, 'Albania': {'Gold': 0, 'Silver': 0, 'Bronze': 0, 'Total': 0}, 'Algeria': {'Gold': 5, 'Silver': 4, 'Bronze': 8, 'Total': 17}}

def rank_countries(dict1):
	if isinstance(dict1, dict):
		for i in dict1:
			if isinstance(dict1[i], dict):
				new_list = [(k, v['Total']) for k, v in dict1.items()]
				new_list=sorted(new_list, key= lambda tup: tup[1], reverse= True) 
				for rank in range (len (new_list)) :
					new_list [rank] = (rank+1,) + new_list [rank]
				return new_list
			else :
				return 'Input must be a nested dictionary.'
	else :
		return 'Input must be a nested dictionary.'

print (rank_countries (tester))
Output:
[(1, 'Algeria', 17), (2, 'Afghanistan', 2), (3, 'Albania', 0)]
As this is homework I skip validation part, but sorting can be alternatively done this way as well (not optimal regarding memory):

>>> tester = {'Afghanistan': {'Gold': 0, 'Silver': 0, 'Bronze': 2, 'Total': 2},
...           'Albania': {'Gold': 0, 'Silver': 0, 'Bronze': 0, 'Total': 0}, 
...           'Algeria': {'Gold': 5, 'Silver': 4, 'Bronze': 8, 'Total': 17}}
>>> sorted_by_medals = sorted(tester.items(), key=lambda x: x[1]['Total'], reverse=True)
>>> [(i, key, value['Total']) for i, (key, value) in enumerate(sorted_by_medals, start=1)]
[(1, 'Algeria', 17), (2, 'Afghanistan', 2), (3, 'Albania', 0)]