-2

Let's say I have two lists

future_ranking = [3, 6, 9, 6]
games_played  = [1, 3, 3, 2]

Now my goal is to convert this into a ranking of indexes [2, 3, 1, 0] This would be the expected output. Problem is, I did my cool lambda function okay?

my_cool_lambda = sorted(range(len(future_ranking)), key = lambda x: future_ranking[x], reverse = True)

And at first I was like, damn, everything is going super fine! I'm totally gonna be a programmer one day. Until I realized that my cool lambda function, when two scores are the same, it gives the higher spot to whatever index comes first, and that's not what I want. The higher spot in case of a tie in points should be given to the index that played less games.

So the output I get is

[2, 1, 3, 0]

And the output i want is

[2, 3, 1, 0]

Does anyone knows how can I fix this? I know it's not like cool to ask "hey can you basically do this for me?" but I have no clue rn and I swear I tried a lot.

esqew
  • 42,425
  • 27
  • 92
  • 132
  • 1
    You spend many words on socialising in your post (something most here would rather see your post without), but not that many on actually explaining the problem you're trying to solve. Are you looking for indices into `future_ranking` and `games_played`, ordered by ranking over games played and by most games played if ranking over games played is equal? – Grismar Nov 01 '21 at 00:19
  • Hey, yes, I'm looking exactly for that. Sorry for the social part – Kumokomari Nov 01 '21 at 00:24
  • `6/3` is `2`, while `3/1` is `3`, why would you want `[... , 1, 0]` instead of `[... , 0, 1]`? – Grismar Nov 01 '21 at 00:29
  • if a team played less games it gets ranked higher if it has the same number of points of another team – Kumokomari Nov 01 '21 at 00:35

3 Answers3

0

Create a ranking that break the ties:

future_ranking_with_tiebreakers = [(rk, -1 * gp) for rk, gp in zip(future_ranking, games_played)]

ranking = sorted(range(len(future_ranking)), key=lambda x: future_ranking_with_tiebreakers[x], reverse=True)
print(ranking)

Output

[2, 3, 1, 0]

The variable future_ranking_with_tiebreakers points to a list of tuples. In case the value in future_ranking is the same it will use the second component to break the ties, giving more weight to those who has played less games (-1 * gp).

Read this to understand better how tuple comparison works.

Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
0

Why not just run sorted() twice (as prescribed by this helpful SO answer) to ensure tiebreakers are sorted properly?

future_ranking = [3, 6, 9, 6]
games_played  = [1, 3, 3, 2]
my_cool_lambda = sorted(sorted(range(len(future_ranking)), key = lambda x: games_played[x], reverse = False), key = lambda x: future_ranking[x], reverse = True)
print(my_cool_lambda) # [2, 3, 1, 0]

Replit

esqew
  • 42,425
  • 27
  • 92
  • 132
0

Take both aspects into account.

sorted(range(len(future_ranking)),
       key=lambda x: (-future_ranking[x], games_played[x]))
no comment
  • 6,381
  • 4
  • 12
  • 30