Page 1 of 1

Order Players by multiple values

Posted: Fri Sep 16, 2016 3:58 pm
by decompile
Hey,

I was wondering how I can create a dict which is sorted by multiple arguments (INT).

So lets say I have a class

Syntax: Select all

class Player(object):
def __init__(self, account_name, isActive, level, inStart):
self.name = account_name
self.isActive = isActive
self.level = level
self.inStart= inStart


dict for all players

Syntax: Select all

players = {0: Player('Sir Lancelot', True, 2, 0),
1: Player('Sir Gallahad', False, 1, 1),
2: Player('Sir Robin', True, 2, 1),
3: Player('King Arthur', True, 1, 0),
4: Player('Robin Hood', True, 3, 1)
}


And now I need to return a list of all players, which have isActive and, are ordered by level (INT/ASC-Highest first, Lowest last) and by inStart the opposite (INT/DESC, Lowest first, highest last)

So in the end it could look like:

Code: Select all

Robin Hood
Sir Robin
Sir Lancelot
King Arthur


Thanks

Re: Order Players by multiple values

Posted: Fri Sep 16, 2016 4:11 pm
by satoon101
Python's builtin sorted function allows for multiple keys. For example:
https://github.com/satoon101/MostDamage ... ge.py#L121

Re: Order Players by multiple values

Posted: Fri Sep 16, 2016 4:22 pm
by decompile
satoon101 wrote:Python's builtin sorted function allows for multiple keys. For example:
https://github.com/satoon101/MostDamage ... ge.py#L121


This is maybe good, but I have no clue how I can use for one "sort" reverse=False and for the other one reverse=True.

As I said, i need level from highest to lowest, and inStart from lowest to Highest

Re: Order Players by multiple values

Posted: Fri Sep 16, 2016 4:58 pm
by iPlayer

Syntax: Select all

sorted(players.values(), key=lambda player: (-player.level, player.inStart))


satoon101 wrote:Python's builtin sorted function allows for multiple keys. For example:
https://github.com/satoon101/MostDamage ... ge.py#L121

It's not really a feature of the sorted itself, more like Python's ability to compare tuples by their first item, then by the second, etc.

Syntax: Select all

(0, 0, 1) > (0, 0, 0)   # True
(1, 0, 0) > (0, 2, 0) # True

Re: Order Players by multiple values

Posted: Fri Sep 16, 2016 10:59 pm
by satoon101
Did you attempt to use what I linked you to? Cause it prints it correctly in the order you provided at the bottom of your first post.

Syntax: Select all

>>> class Player(object):
def __init__(self, account_name, isActive, level, inStart):
self.name = account_name
self.isActive = isActive
self.level = level
self.inStart= inStart


>>> players = {0: Player('Sir Lancelot', True, 2, 0),
1: Player('Sir Gallahad', False, 1, 1),
2: Player('Sir Robin', True, 2, 1),
3: Player('King Arthur', True, 1, 0),
4: Player('Robin Hood', True, 3, 1)
}

>>> filtered_players = filter(lambda player: players[player].isActive, players)
>>> sorted_players = sorted(filtered_players, key=lambda player: (players[player].level, players[player].inStart), reverse=True)
>>> for player in sorted_players:
print(players[player].name)


Robin Hood
Sir Robin
Sir Lancelot
King Arthur

Though now I see that isn't really the order you want, and instead you want the middle 2 reversed from each other. In that case, as iPlayer mentioned, just use - in front of the first and remove the reverse, or keep the reverse and add the - in front of the second.

Re: Order Players by multiple values

Posted: Fri Sep 16, 2016 11:25 pm
by decompile
Both ways work!

Thank you guys.

@satoon101

It was my bad, I havent understood sorted until iPlayers post.