0
votes

I am trying to implement a procedure that involves coupled element counts and sorting. However, I got stuck.

Here is an example:

olimpic=[['Russia', 'bronze', 'basketball_male'],
 ['China', 'gold', 'soccer_female'],
 ['China', 'silver', 'judo_male_100kg'],
 ['Australia', 'gold', 'surf_male'],
 ['Cuba', 'gold', 'gymnastics_solo_female'],
 ['Russia', 'silver', 'karate_female_60kg'],
 ['China', 'silver', 'voleyball_female']]

This is what I've already done:

short=[]

for i in range(len(olimpic)):
    short.append([olimpic[i][0],olimpic[i][1]])
    
countrySort=sorted(short, key=lambda element: (element, element[1]))

print (countrySort)

My current output is:

[['Australia', 'gold'],
 ['China', 'gold'],
 ['China', 'silver'],
 ['China', 'silver'],
 ['Cuba', 'gold'],
 ['Russia', 'bronze'],
 ['Russia', 'silver']]

However, I have to do other three steps:

  1. Make a paired count of the country and type of medal

  2. Sort according the number of type of medal, keeping in mind that; gold > silver > bronze regardless the number of medals in the lower levels.

  3. When two or more countries have exactly the same number of types of medals, sort them by their names

the output should be like this (a list of tuples):

Rank of the countries:
    
(1, 2, 0, 'China')
(1, 0, 0, 'Australia')
(1, 0, 0, 'Cuba')
(0, 1, 1, 'Russia')
3
It is better to add your trial code about ` I have to do other three steps:`.Nour-Allah Hussein

3 Answers

0
votes
olympic=[['Russia', 'bronze', 'basketball_male'],
 ['China', 'gold', 'soccer_female'],
 ['China', 'silver', 'judo_male_100kg'],
 ['Australia', 'gold', 'surf_male'],
 ['Cuba', 'gold', 'gymnastics_solo_female'],
 ['Russia', 'silver', 'karate_female_60kg'],
 ['China', 'silver', 'voleyball_female']]

short=[]
for i in range(len(olympic)):
    short.append([olympic[i][0],olympic[i][1]])

medal_dict = {'bronze':2,'silver':1,'gold':0}

ret={}
for x in short:
  if x[0] not in ret.keys():
   ret.update({x[0]:(0,0,0)})
  temp = [y for y in ret[x[0]]]
  temp[medal_dict[x[1]]] += 1
  ret[x[0]]=tuple([y for y in temp])

print(sorted(ret.items(),key = lambda x:x[1][1]))

## [('Australia', (1, 0, 0)), ('Cuba', (1, 0, 0)), ('Russia', (0, 1, 1)), ('China', (1, 2, 0))]
0
votes

So first we create the following dictionary:

{'Russia': [0, -1, -1, 'Russia'], 'China': [-1, -2, 0, 'China'], 'Australia': [-1, 0, 0, 'Australia'], 'Cuba': [-1, 0, 0, 'Cuba']}

Insert the values into an array:

[[0, -1, -1, 'Russia'], [-1, -2, 0, 'China'], [-1, 0, 0, 'Australia'], [-1, 0, 0, 'Cuba']]

Sort the array

[[-1, -2, 0, 'China'], [-1, 0, 0, 'Australia'], [-1, 0, 0, 'Cuba'], [0, -1, -1, 'Russia']]

And then we invert the medal counts from negative to positive, and convert the subarrays into tuples.

[(1, 2, 0, 'China'), (1, 0, 0, 'Australia'), (1, 0, 0, 'Cuba'), (0, 1, 1, 'Russia')]

We store the initial medal counts as a negative number because we want to sort medal counts in descending order, but strings in ascending order. This will allow us to simply call the .sort() method to sort the array as we want. We can then convert the medal counts back into a positive value for our final output.

olimpic=[['Russia', 'bronze', 'basketball_male'],
    ['China', 'gold', 'soccer_female'],
    ['China', 'silver', 'judo_male_100kg'],
    ['Australia', 'gold', 'surf_male'],
    ['Cuba', 'gold', 'gymnastics_solo_female'],
    ['Russia', 'silver', 'karate_female_60kg'],
    ['China', 'silver', 'voleyball_female']]

short=[]

for i in range(len(olimpic)):
    short.append([olimpic[i][0],olimpic[i][1]])

country_to_medal_counts_map = {}
medal_to_indice_map = {'gold': 0, 'silver': 1, 'bronze': 2}

for country, medal in short:
    if country not in country_to_medal_counts_map:
        country_to_medal_counts_map[country] = [0,0,0,country]
    country_to_medal_counts_map[country][medal_to_indice_map[medal]] -= 1

country_rankings = [medal_counts for medal_counts in country_to_medal_counts_map.values()]
country_rankings.sort()
country_rankings = [tuple([gold*-1, silver*-1, bronze*-1, country]) 

for gold, silver, bronze, country in country_rankings]
        
        
print (country_rankings)
# [(1, 2, 0, 'China'), (1, 0, 0, 'Australia'), (1, 0, 0, 'Cuba'), (0, 1, 1, 'Russia')]
0
votes
from collections import defaultdict

olimpic=[
 ['Russia', 'bronze', 'basketball_male'],
 ['China', 'gold', 'soccer_female'],
 ['China', 'silver', 'judo_male_100kg'],
 ['Australia', 'gold', 'surf_male'],
 ['Cuba', 'gold', 'gymnastics_solo_female'],
 ['Russia', 'silver', 'karate_female_60kg'],
 ['China', 'silver', 'voleyball_female'],
 ['Canada', 'silver', 'voleyball_female'],
 ['Canada', 'silver', 'voleyball_female'],
 ['Canada', 'gold', 'voleyball_female']]


d = defaultdict(lambda: defaultdict(int))

for x, y, z in olimpic:
    d[x].setdefault('gold', 0)
    d[x].setdefault('silver', 0)
    d[x].setdefault('bronze', 0)
    d[x][y] += 1

class C:
    def __init__(self, key):
        self.key = key
        self.values = tuple(d[key].values())

    def __lt__(self, other):
        if self.values == other.values:
            if self.key < other.key:
                return True
        else:
            if self.values > other.values:
                return True

l = []

for i in sorted(d, key=C):
    l.append(tuple((*d[i].values(), i)))

print(f'Rank of the Countries\n{chr(10).join([str(i) for i in l])}')
Rank of the Countries
(1, 2, 0, 'Canada')
(1, 2, 0, 'China')
(1, 0, 0, 'Australia')
(1, 0, 0, 'Cuba')
(0, 1, 1, 'Russia')