2

Hello I am somewhat new to python so please bear with me.

My python program has the following lines:

print "Player 1: " +str(player1points)

print "Player 2: " +str(player2points)

print "Player 3: " +str(player3points)

print "Player 4: " +str(player4points)

The player#points are what my program has calculated it to be, so differs everytime I run it.

The result would yield:

Player 1: 3

Player 2: 4

Player 3: 3

Player 4: 5

If possible, I want to sort the result so that each player's points is ranked from highest to lowest first, then the player. If two players are tied for points, then the player with the lowest number will be listed first.

So I expect my results to be like:

Player 4: 5

Player 2: 4

Player 1: 3

Player 3: 3

Any help would be much appreciated!!

3
  • 2
    You need to tell us what have you tried and where you failed. Commented Apr 10, 2011 at 18:21
  • 1
    Can you sort them before they become one string, ie. when you have the scores and the player id's separately? Commented Apr 10, 2011 at 18:21
  • How are these players represented in your code? Commented Apr 10, 2011 at 18:22

5 Answers 5

2

Look at the examples of

http://wiki.python.org/moin/HowTo/Sorting#Operator_Module_Functions

Sign up to request clarification or add additional context in comments.

Comments

1

If you already have player objects or dictionaries, you could sort with:

players.sort(key=lambda player: player.score, reverse=True)

If not, process your array and split at each ':'

Sample:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def main():
    "entry point"
    player_strings = ['Player 1:3', 'Player 2:4', 'Player 3:3', 'Player 4:5']
    players = []
    for player_string in player_strings:
        name, score = player_string.split(':')
        players.append({'name':name, 'score':score})
    players.sort(key=lambda player: int(player['score']), reverse=True)
    for player in players:
        print ('%s has a score of %s' % (player['name'], player['score']))

if __name__ == '__main__':
    main()

Comments

0
sorted(values, key=lambda s: s.split(': ')[1], reverse=True)

Comments

0

Passing a "key function" to the list.sort method allows you to customize how it is sorted.

def sort_players(players):
    r"""Sort the players by points.

    >>> print sort_players('Player 1: 3\n'
    ...                    '\n'
    ...                    'Player 2: 4\n'
    ...                    '\n'
    ...                    'Player 3: 3\n'
    ...                    '\n'
    ...                    'Player 4: 5\n')
    Player 4: 5
    Player 2: 4
    Player 1: 3
    Player 3: 3
    """
    # split into a list
    players = players.split("\n")

    # filter out empty lines
    players = [player for player in players if player != '']

    def points(player_report):
        """Parse the number of points won by a player from a player report.

        A "player report" is a string like 'Player 2: 6'.
        """
        import re
        # Match the last string of digits in the passed report
        points = re.search(r'\d+$', player_report).group()
        return int(points)

    # Pass `points` as a "key function".
    # The list will be sorted based on the values it returns.
    players.sort(key=points, reverse=True)

    # Make the sorted list back into a string.
    return "\n".join(players)

7 Comments

This answer was really helpful! However for my program I have it set as "Player 1:" +str(player1points), instead of just "Player 1: 3" Where player1points is assigned to whatever the program calculates it to be. How will I go about to using this function to accept my string?
@Bob Loin: Not sure if I understand you. The regular expression used by the points function will find the last string of digits (\d+) in a given "player report". I'm using the term "player report" to refer to a string like Player 2: 6. So as long as your player1points is a positive integer at the end of the report string, points will return it as an integer.
Sorry, I'm a total newbie when it comes to this.
When I type this into my program: print "Player 1: " +str(player1points), it will give me the following result: Player 1: 1. However, when I input: sort_players('Player 1: +str(player1points)\n'), it gives me error: AttributeError:'NoneType' object has no attribute 'group'.
@Bob Loin: Wait.. you're literally typing sort_players('Player 1: +str(player1points)\n')? So then the last character in the first (and only) player report line is ). If the last character of a player report is any non-digit, you'll get that error message, because points expects the report to end with an integer. It's not particularly robust, but making it robust is a bit more complicated.
|
0

Supposing that the 'players reports' are in a list:

values = ['Player 1: 3','Player 2: 4','Player 3: 3','Player 4: 5']

values.sort(key=lambda s: [(-int(b),a) for a,b in (s.split(':'),)])

print values

results in

['Player 4: 5', 'Player 2: 4', 'Player 1: 3', 'Player 3: 3']

=============

Bob Loin said he wants to obtain

Player 4: 5, Player 2: 4, Player 1: 3, Player 3: 3

Daniel's Roseman works well or not depending on the treated list.

My solution gives the right result. See the difference on the second list

values = ['Player 1: 3','Player 2: 4','Player 3: 3','Player 4: 5']

print '   ',values
print
print 'Dan',sorted(values, key=lambda s: s.split(': ')[1], reverse=True)
print 'eyq',sorted(values, key=lambda s: [(-int(b),a) 
                                          for a,b in (s.split(':'),)])

print '\n===================================\n'

values = ['Player 3: 3','Player 2: 4','Player 1: 3','Player 4: 5']

print '   ',values
print
print 'Dan',sorted(values, key=lambda s: s.split(':')[1], reverse=True)
print 'eyq',sorted(values, key=lambda s: [(-int(b),a) 
                                          for a,b in (s.split(': '),)])

result

    ['Player 1: 3', 'Player 2: 4', 'Player 3: 3', 'Player 4: 5']

Dan ['Player 4: 5', 'Player 2: 4', 'Player 1: 3', 'Player 3: 3']
eyq ['Player 4: 5', 'Player 2: 4', 'Player 1: 3', 'Player 3: 3']

===================================

    ['Player 3: 3', 'Player 2: 4', 'Player 1: 3', 'Player 4: 5']

Dan ['Player 4: 5', 'Player 2: 4', 'Player 3: 3', 'Player 1: 3']
eyq ['Player 4: 5', 'Player 2: 4', 'Player 1: 3', 'Player 3: 3']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.