Pythonner
Pythonner

Reputation: 1

Sorting a list alphabetically, whilst maintaining previous index

I have a personal project in which I have a list of name's and 3 scores corresponding to a certain name. However, I would like to 'sort' this list into alphabetical order, whilst maintaining the previous index so that I could link the score's. What I would like to achieve is being able to sort this list into alphabetical order, and print the score(s) corresponding to the name, I do not see how I can make this more concise and informative.

Here is some of my code:

Names = ['Fred', 'John', 'Sally']
Scores = [1,5,9,2,4,6,3,6,5]
for i in range(0, len(Names)):
    print("The score(s) for", Names[i], "is:", Scores[i], Scores[i+3], Scores[i+6])`

Therefore, for example, my preferred result for this program, when sorted, would be:

The score(s) for John is: 5, 4, 6 etc...

Upvotes: 0

Views: 705

Answers (7)

Saksham Varma
Saksham Varma

Reputation: 2140

scores = [Scores[i:i+3] for i in range(0, len(Scores), 3)]
print sorted([(name, all_scores) for name, all_scores in zip(Names, zip(*scores))])

Upvotes: 0

dersvenhesse
dersvenhesse

Reputation: 6424

If you're assuming every name is unique, this can be pretty fast forward. You just need to use the index from the unsorted list.

names = ['Fred', 'John', 'Sally', 'Alex']
scores = [1,5,9,7, 2,4,6,8, 3,6,5,9]

l = len(names)
for e in sorted(names):
    i = names.index(e) # index in unsorted list
    print "The score for", e, "is:", scores[i], scores[i+l], scores[i+2*l]

Upvotes: 1

emvee
emvee

Reputation: 4449

Apart from changing your nick, I would suggest:

# rearrange into a list of tuples with (name, [scores]) structure
data = [(name, Scores[idx*3:idx*3+3]) for (idx,name) in enumerate(Names)]

# then sort alphabetically on name
import operator
data = sorted(data, key=operator.itemgetter(0))

Upvotes: 0

Maltysen
Maltysen

Reputation: 1946

This code is very un-pythonic for many reasons.

First of all, just a small thing, you don't want to ever use range(len()). Use enumerate instead as such: for i, val in enumerate(Names):, so you'll get both the index and the value.

Now to your actual problem. You shouldn't be storing the values like that in two separate lists. This is exactly what dictionaries were made for:

scores={"Fred": [1, 2, 3], "John": [5, 4, 6], "Sally": [9, 6, 5]}

Of course, dictionaries can't be sorted since they have no order, so you have to ues OrderedDicts. These are dictionaries that preserve order.

So here's what you should be doing:

from collections import OrderedDict

scores={"Fred": [1, 2, 3], "John": [5, 4, 6], "Sally": [9, 6, 5]}
scores=OrderedDict(sorted(scores.items(), key=lambda t: t[0]))

Voila! And to print it:

for name, score in scores.items():
    print("The scores for {0} are {1}, {2}, and {3}.".format(name, *score))

Upvotes: 0

Chad Miller
Chad Miller

Reputation: 1475

Looks like you should make a new list of indices, and sort that new list.

ordered_name_list = range(len(names))
ordered_name_list.sort(key=lambda item: name[item])

Then, use that ordered name list to pick each name and each offset into Scores. Your list accessing is really unpythonic, too.

for o in ordered_name_list:
    print("The scores for {0} are {1}".format(names[o], ", ".join(Scores[o::3])))

Upvotes: 0

Udy
Udy

Reputation: 2542

First start by rearranging your data model, like this:

Names = ['Fred', 'John', 'Sally']
Scores = [1,5,9,2,4,6,3,6,5]

data = {}
for index, name in enumerate(Names):
    data[name] = [Scores[(index * 3)], Scores[(index * 3) + 1], Scores[(index * 3) + 2]]

now data contains:

{'John': [2, 4, 6], 'Sally': [3, 6, 5], 'Fred': [1, 5, 9]}

now you can do whatever you want. to print the names and scores in sorted manner you can:

for name in sorted(data.keys()):
    print name, date[name]

Upvotes: 0

TigerhawkT3
TigerhawkT3

Reputation: 49330

A bunch of arbitrary lists is the wrong data structure to use here. Create a dictionary with a key of the user's name and a value of their list of scores. If you have to start with the given Names and Scores, here's how that's done:

>>> Names=['Fred', 'John', 'Sally']
>>> Scores=[1,5,9,2,4,6,3,6,5]
>>> Scores = [Scores[i:i+3] for i in range(0, len(Scores), 3)]
>>> all_scores = {k:v for k,v in zip(Names, Scores)}
>>> all_scores
{'Sally': [3, 6, 5], 'John': [2, 4, 6], 'Fred': [1, 5, 9]}

Now you can sort and print that dictionary however you like.

Upvotes: 0

Related Questions