1

My problem is I am trying to sort this lists within a dictionary where I am using the dictionary name as the field name and the lists as the data rows. I have a feeling I am using the wrong approach (should this be a tuple or a dataframe or what?)

I have tried using sorted() but can't get past only sorting by the key (e.g. name, score1, score2). I want to maintain the key order but rearrange the values while keeping their relationship across keys.

This is a sample dataset that I want to sort by score1 (or score2):

scores = {'name': ['joe', 'pete', 'betsy', 'susan', 'pat'], 'score1': [99, 90, 84, 65, 100], 'score2': [85, 91, 90, 55, 98]}

After sorting for score1, I would like to see:

pat, joe, pete, betsy, susan

After sorting for score1, I would like to see:

pat, pete, betsy, joe, susan
0

3 Answers 3

2

If you create scores yourself, it will be much easier if it is structured differently, ie [{'name': 'joe', 'score1': 1, 'score2': 2}, ...].

Then the usage of sorted is quite simple:

scores = [{'name': 'joe', 'score1': 99, 'score2': 85},
          {'name': 'pete', 'score1': 90, 'score2': 91},
          {'name': 'betsy', 'score1': 84, 'score2': 90},
          {'name': 'susan', 'score1': 65, 'score2': 55},
          {'name': 'pat', 'score1': 100, 'score2': 98}]

by_score_1 = [d['name'] for d in sorted(scores, key=lambda d: d['score1'], reverse=True)]
print(by_score_1)
by_score_2 = [d['name'] for d in sorted(scores, key=lambda d: d['score2'], reverse=True)]
print(by_score_2)

Outputs:

['pat', 'joe', 'pete', 'betsy', 'susan']
['pat', 'pete', 'betsy', 'joe', 'susan']
Sign up to request clarification or add additional context in comments.

3 Comments

...this is more efficient and clearer than what i suggested!
I can restructure scores, so this looks interesting. I then need to add new keys as new tests are created. This seems easily done by: for item in scores: item.update( {'score3': 90}) But what if I then needed to update individually by student? How could I update 'Pat' to a new score 3 of 75?
@DouglasWood That's a very valid argument, for which the data structure I suggested is a bit less efficient. You will need to iterate over the entire list until you find the correct dictionary: for person_data in scores: if person_data['name'] == 'pat': person_data['score1'] = new_score
2

The other answer is nice. You could also turn it into a list of tuples then easily sort it:

scores = {
    'name': ['joe', 'pete', 'betsy', 'susan', 'pat'], 
    'score1': [99, 90, 84, 65, 100], 
    'score2': [85, 91, 90, 55, 98]}

t = list(zip(*scores.values()))
print(t)

Output:

[('joe', 99, 85), ('pete', 90, 91), ('betsy', 84, 90), ('susan', 65, 55), ('pat', 100, 98)]

Then you can sort it:

# Sort by score1
print(sorted(t, key=lambda x: (x[1]), reverse=True))

# Sort by score2
print(sorted(t, key=lambda x: (x[2]), reverse=True))

# Sort by both scores:
print(sorted(t, key=lambda x: (x[1], x[2]), reverse=True))

Just a different way to attack the same problem. Doing it this way you can easily print the scores of the individuals as well.

Comments

1

this is a possiblity:

print(sorted(scores['name'], reverse=True, 
             key=lambda x: scores['score1'][scores['name'].index(x)]))
# ['pat', 'joe', 'pete', 'betsy', 'susan']
print(sorted(scores['name'], reverse=True, 
             key=lambda x: scores['score2'][scores['name'].index(x)]))
# ['pat', 'pete', 'betsy', 'joe', 'susan']

1 Comment

What if I wanted to display the name and the score? Also, what if I wanted to not just print but update the dictionary to be in sorted order by score1?

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.