1

I've been trying to figure out how to sort results in a text file in order of test scores for a small task I'm doing using the lambda sort function. I'm unsure if this is the best way to do this or not but it was recommended to me by a friend.

The results are entered into the text file like so:

    text_file = open("Results.txt", "a")
    text_file.write("\n")
    text_file.write(str(score))
    text_file.write(" ")
    text_file.write(userName)
    text_file.write(" ")
    text_file.write(userClass)
    text_file.close()

My current sorting system looks like this:

with open("Results.txt") as inf:
data = []
for line in inf:
    line = line.split()
    if len(line)==4:
        data.append(line)

a = sorted(a, key=lambda x: x.modified, reverse=True)

And the text file looks like this:

5 Test b
4 Test b
6 Test c
7 Test a

(score userName userClass)

I would like to sort the results in descending order by score and I'm not sure this is the correct way to go about it.

Thanks in advance.

6
  • What is x.modified? Commented Apr 29, 2015 at 17:10
  • Have you tried running the code? What results do you get? Commented Apr 29, 2015 at 17:11
  • Why if len(line)==4: when you only have 3 elements in each line (score, userName and userClass)? Commented Apr 29, 2015 at 17:17
  • what is a supposed to be in your code? And dtw, you have to add a level of indentation after with open... Commented Apr 29, 2015 at 17:21
  • as @BhargavRao asks, x.modified has no meaning. Your data list consists of lists with 3 elements. So you should use key=lambda x: x[0] instead. Commented Apr 29, 2015 at 17:22

4 Answers 4

1

You want to sort on the first index of each x passed to your lamda, which will be an array in this case. This code works for me (plus a few other changes to variables to make it work, as your example had invalid formatting, passed a instead of data to the sorted() function, and was only working on lines of 4 elements, not 3):

with open("Results.txt") as inf:
    data = []
    for line in inf:
        line = line.split()
        if len(line) == 3:
            data.append(line)

    a = sorted(data, key=lambda x: x[0], reverse=True)
Sign up to request clarification or add additional context in comments.

2 Comments

This didn't work for me. I got no errors just doesn't sort results.
Here is a working example that you can take a look at. I'm guessing that due to the other errors in your sample, there's something else that's preventing you from being to integrate my answer.
0

if you need list element as sublists, the above answers are ok. but if your need is just to sort the results

with open("Results.txt") as inf:
data = []
for line in inf:
    line = line.split()
    if len(line)==3:
        data.append(tuple(line)) #append as tuple

>>> data #as result of codes
[('5', 'Test', 'b'), ('4', 'Test', 'b'), ('6', 'Test', 'c'), ('7', 'Test', 'a')]
>>> data.sort()
>>> data #ascending order
[('4', 'Test', 'b'), ('5', 'Test', 'b'), ('6', 'Test', 'c'), ('7', 'Test', 'a')]
>>> data.sort(reverse=True)
>>> data # descending order
[('7', 'Test', 'a'), ('6', 'Test', 'c'), ('5', 'Test', 'b'), ('4', 'Test', 'b')]

then do whatever you want

edit

>>> for t in data:
...     print  " ".join(t)
... 
7 Test a
6 Test c
5 Test b
4 Test b

edit 2.1 avoiding duplicates with set()

>>> with open('ex4.txt') as inf:
...     data = set()
...     for line in inf:
...             line = line.split()
...             if len(line)==3:
...                     data.add(tuple(line))
... 
>>> data
set([('2', 'Test', 'c'), ('0', 'Test', 'a'), ('1', 'Test', 'a'), ('3', 'Test', 'b')])
>>> list(data)
[('2', 'Test', 'c'), ('0', 'Test', 'a'), ('1', 'Test', 'a'), ('3', 'Test', 'b')]
>>> 

edit 2.2 avoiding duplicate records with if

>>> with open("ex4.txt") as inf:
...     data = []
...     for line in inf:
...             line = line.split()
...             if (len(line)==3) and (tuple(line) not in data): 
...                     data.append(tuple(line))
... 
>>> data
[('1', 'Test', 'a'), ('2', 'Test', 'c'), ('3', 'Test', 'b'), ('0', 'Test', 'a')]

5 Comments

Solution works perfectly :D but is there a way I can split them off and display each score on a separate line?
This is creating a double of a score every time its position in the list is changed...any way to delete previous results once they have been moved in the list?
excuse me, i didn't understand what you mean. can you just give an example?
1 Test a 2 Test c 3 Test b 0 Test a 3 Test b In this the result with score 3 has been in the file for the longest and has created duplicates because of this I can only assume. It seems that sorting it recreates results that were already in there and displays them in the correct order.
adding and tuple(line) not ind data to if statement will solve it. or assigning data as a set() and adding tuples to this set, then convert in back to list is also possible solution. i'm updating the code.
0

You can use the sort() method which modifies the list in-place. Your input file looks pretty straight forward that you can use a list comprehension to read it in. Since you know that the grades are in index 0, the key should be based on that index.

 with open("Results.txt", 'r') as f:
    data = [line.split() for line in f]
    data.sort(key = lambda x : x[0], reverse=True)

Comments

0

Do you want to process the sorted data or just have it printed?

>>> f = open('Results.txt')
>>> print '\n'.join(' '.join(l)for l in sorted((l.split()for l in f),
                                            key=lambda x: -int(x[0])))
7 Test a
6 Test c
5 Test b
4 Test b
>>> 

More seriously, if your scores are integers usually you don't want to sort them in lexicographical order, otherwise "7" comes before "11" in reversed order...

Your lambda must (must) convert the string that comes from split to an integer and then pass the result to sorted; a more straightforward way to put it is

>>> f = open('Results.txt')
>>> data = [l.split() for l in f]
>>> data.sort(key=lambda x: -int(x[0]))

Example

This is a direct cut&paste from the terminal:

$ cat Results.txt 
5 Test b
4 Test b
6 Test c
7 Test a
$ python
Python 2.7.9 (default, Mar  1 2015, 12:57:24) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('Results.txt')
>>> print '\n'.join(' '.join(l)for l in sorted((l.split()for l in f),
...                                             key=lambda x: -int(x[0])))
7 Test a
6 Test c
5 Test b
4 Test b
>>> f = open('Results.txt')
>>> data = [l.split() for l in f]
>>> data.sort(key=lambda x: -int(x[0]))
>>> data
[['7', 'Test', 'a'], ['6', 'Test', 'c'], ['5', 'Test', 'b'], ['4', 'Test', 'b']]
>>> 

The OP, in a comment, remarked a problem with an IndexError that I cannot replicate in my example... I can only guess that they are blindly applying my suggestion, that is linked to a specific data format, to a different use case...

2 Comments

Getting this error: line 118, in <lambda> key=lambda x: -int(x[0])))) IndexError: list index out of range Unsure what it means...fairly new to python.
Your error usually happens when x (the individual item that is to be sorted) is not an indexable object, on the other hand the elements that are being sorted should be lists... Is it possible that a mistake happened when you copy&pasted my code?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.