Zipped lists in Python are being sorted incorrectly

Viewed 146

I am trying to sort strings and integers together from two text files. This is to replicate the structure of game high-score boards, where a player's name and position correlates to their high score. I am using Python to sort through two text files, one with player names, and one with player scores. They are named "players.txt" and "scores.txt", respectively. However, whenever I sort the information together, my list of integers is correct, but the names get jumbled, and have no (apparent) order to them. Does anyone know my error?

Here is my code:

line_count = 0


def get_file_length():
    global line_count

    # Open file
    file = open("scores.txt", "r")

    # For each line in the whole file...
    for line in file:

        # ...if the line is not empty, increment "line_count"
        if line != "\n":
            line_count += 1

    # Close read-mode on file
    file.close()

    # Print how many stored scores are present
    print("There are " + str(line_count) + " lines in this file.")


def get_zipped():
    global line_count

    # Set text file to get scores from
    scores_list = open("scores.txt", "a+")
    players_list = open("players.txt", "r")

    # Go to beginning of text file
    scores_list.seek(0)
    players_list.seek(0)

    # Create new array to hold text files' contents as list
    stored_scores = []
    stored_players = []

    for item in range(line_count):
        stored_scores.append(scores_list.readline())
        stored_scores[item] = int(stored_scores[item].rstrip("\n"))

        stored_players.append(players_list.readline())
        stored_players[item] = str(stored_players[item].rstrip("\n"))

    zipped_players = [x for _, x in sorted(zip(stored_scores, stored_players))]
    zipped_players.sort(reverse=True)

    zipped_scores = [y for _, y in sorted(zip(zipped_players, stored_scores))]
    zipped_scores.sort(reverse=True)

    print(str(zipped_players))
    print(str(zipped_scores))


get_file_length()
get_zipped()

For example, say my two texts files are the following:

players.txt and scores.txt example

My desired output would be...

There are 5 lines in this file.
['Jregory', 'Javonte', 'Jackie', 'Jamil', 'Joises']
[420, 99, 65, 13, 3]

However, the terminal shows the following:

There are 5 lines in this file.
['Jregory', 'Joises', 'Javonte', 'Jamil', 'Jackie']
[420, 99, 65, 13, 3]

What is going wrong here? If you could either point me towards any resources or provide a solution, that would be greatly appreciated. Thank you in advance.

3 Answers

You can just specify the key for sorting.

players, scores = 
   [list(x) for x in zip(*sorted(zip(players, scores), key=lambda x:x[1], reverse=True))]
print(players)
print(scores)

This code should work:

zipped_values = [y for y in sorted(zip(zipped_players, stored_scores), key=lambda x: x[1], reverse=True)]
zipped_scores = [x[1] for x in zipped_values]
zipped_players = [x[0] for x in zipped_values]
print(zipped_scores)
print(zipped_players)

Adding a key specifies that you want to sort this list on the second element (that is, the score). Otherwise the sorting happens on the entire tuples, which sorts on the 1st element, and then sorts on the 2nd to break ties, etc.

I just want to point out that you are opening the file just to get the count. This is not quite practical. Second, since you are interested to sort by scores, you can either define a key with a lambda function or just put scores as the first argument in the zip function as this is the default behavior for sorted function. I believe the following code should make more sense:

    with open('scores file','r') as scores_file, open('players file','r') as players_file:
        scores = scores_file.read().split_lines()
        players = players_file.read().split_lines()
        sorted_scores_players = sorted(zip(scores,players),reverse=True)
        sorted_players = [player for score,player in sorted_scores_players]
        sorted_scores = [score for score,player in sorted_scores_players]
        print(sorted_scores)
        print(sorted_players)
Related