Search code examples
pythonsortingpython-3.x

Sorting names by their high scores


I want to sort a list of names by their score. What I have so far is

file = open("scores.txt", 'r')
for line in file:
    name = line.strip()
    print(name)
file.close()

I'm unsure how to sort them.

Here's the file contents:

Matthew, 13
Luke, 6
John, 3
Bobba, 4

What I want the output to be:

John 3
Bobba 4
Luke 6
Matthew 13

Can anyone help?


Solution

  • you can use the .split(',') method to split a line into its separate parts, then use int() to convert the score to a number. The .sort() method sorts a list in place, and the key tells it what to sort by.

    scores = []
    with open("scores.txt") as f:
        for line in f:
            name, score = line.split(',')
            score = int(score)
            scores.append((name, score))
    
    scores.sort(key=lambda s: s[1])
    
    for name, score in scores:
        print(name, score)
    

    This will give you a list of tuples containing (name, score) pairs in sorted order. If you want to print them out with a comma in between them (to keep it consistent) change the print to print(name, score, sep=', ')

    The reading of the input file can also be expressed as one (big) line

    with open("scores.txt") as f:
        scores = [(name, int(score)) for name, score in (line.split(',') for line in f)]
    

    or with python 3.8+ assignment expression

    with open("scores.txt") as f:
        scores = [((parts := line.split(','))[0], int(parts[1])) for line in f]
    

    A brief explanation of the key=:

    a lambda function is an anonymous function, that is, a function without a name. You generally use these when you need a function only for a small operation. .sort has an optional key keyword argument that takes a function and uses the return of that function in sorting the objects.

    So this lambda could also be written as

    def ret_score(pair):
        return pair[1]
    

    And you could then write .sort(key=ret_score) but since we dont really need that function for anything else, its not necessary to declare it. The lambda syntax is

    lambda <arguments> : <return value>
    

    So this lambda takes a pair, and returns the second element in it. You can save a lambda and use it like a regular function if you wish.

    >>> square = lambda x: x**2 # takes x, returns x squared
    >>> square(3)
    9
    >>> square(6)
    36