问题
I have tried multiple methods in doing this but none of them seem to work The answer comes up alphabetically instead
f=open("class2.txt", "r")
scores=myfile.readlines()
print(sorted(scores))
f.close()
['Anne, 3\n', 'Dave, 10', 'Jack, 4\n', 'Lucy, 8\n']
Also is there any way to get rid of the "/n" when it goes to the shell?
回答1:
Based on the inputs and outputs, I'm guessing you're trying to sort the input names by the associated values. To sort numerically, you can either parse all the values pairs, or use a key function with sorted that does it for you (without storing the result anywhere). For example:
# This could be a lambda function, but I'm splitting it out for clarity
def getlinevalue(line):
intpart = line.split()[-1] # Get the last whitespace separated group (assumed to be legal integer)
return int(intpart) # Convert to int, which will sort numerically
with open("classt2.txt") as f:
stripnewlines = (line.rstrip() for line in f)
# reverse=True needed to sort highest to lowest; natural sort for int is lowest to highest
print(sorted(stripnewlines, reverse=True, key=getlinevalue))
# If the goal is to print one pair per line, replace the print above with:
for x in sorted(stripnewlines, reverse=True, key=getlinevalue):
print(x)
# Or as a one liner (require Py3, or from __future__ import print_function on Py2):
print(*sorted(stripnewlines, reverse=True, key=getlinevalue), sep="\n")
The output from print(sorted(stripnewlines, reverse=True, key=getlinevalue)) would be (modulo some whitespace; the screenshot makes it hard to tell how much whitespace is after the comma, so I'm just using a single space):
['Dave, 10', 'Lucy, 8', 'Jack, 4', 'Anne, 3']
which is what you seem to want.
Explanation of code as requested in the comments:
- In
getlinevalue, we're splitting the provided string on whitespace (str.split does this when not given an argument), then taking the last value from the split with[-1](indexing with negative numbers starts from the end). So something like'Dave, 10'is stored tointpartas'10'. Then we convert the string'10'to its integer value with int() and return it with open("classt2.txt") as f:opens the file for read and assigns the result tof; when the indented with block finishes, the file is closed for you (even if the block exits due to exceptions or returning from a function)stripnewlines = (line.rstrip() for line in f)Creates a generator expression (sort of like a lazily evaluated list comprehension that can only be iterated once) that reads a line at a time and uses str.rstrip() to remove all trailing whitespace (e.g. the new line; you could usestr.rstrip("\r\n")to only remove the newline, not trailing tabs or spaces, but thekeyfunction would need to be tweaked). We could use a list comprehension instead of a generator expression, but sincesortedwill create thelistfor us anyway, we're being lazy to avoid having both the sorted and unsorted list stored at the same time (alternatively, a list comprehension could be followed by a.sort(...)call on the result, which would also avoid keeping two lists in memory, but.sort(...)doesn't return anything, so we'd have more lines of code).sorted(stripnewlines, reverse=True, key=getlinevalue)is just like the sorted you used in your attempt except it sorts each (rstrip-ed) line based on the result of callinggetlinevalueon it (it only calls thekeyfunction once per value, which is whykeyis superior tocmp;cmpwould have to convert each valuelog(n)times during the sort, on average, orn log(n)conversions total;keyconverts each value once, and performs a total ofnconversions). So it sorts'Dave, 10'relative to'Anne, 3'by comparing the result of callinggetlinevalue('Dave, 10')(10) togetlinevalue('Anne, 3')(3). Since numbers sort in ascending order (lowest to highest) normally (so3would sort before10) and you want descending order (highest to lowest) we also passreverse=Trueto reverse the "natural" sort of the integers.- The final one-liner uses the "splat" operator (
*) to convert the list resulting from thesortedcall to sequential positional arguments toprint; for Python 3's print function (or theprintfunction you get in Python 2 withfrom __future__ import print_functionthat replaces the normalprintstatement of Py2), each argument is printed, withsepprinted between each argument (defaults to a single space,' '), and when all arguments are printed, follows it up with the value ofend(defaults to a new line,"\n"). So that would let you print the input lines from highest to lowest on separate output lines rather than printing the representation of the sorted list on a single line.
回答2:
To sort numerically by grade:
>>> sorted((line.split() for line in open('classt2.txt')), key=lambda x: int(x[1]))
[['Anne,', '3'], ['Jack,', '4'], ['Lucy,', '8'], ['Dave,', '10']]
How it works
The above code has two parts. The first reads the file and splits the lines:
>>> [line.split() for line in open('class')]
[['Anne,', '3'], ['Dave,', '10'], ['Jack,', '4'], ['Lucy,', '8']]
These lines are unsorted.
The next step is to sort the lines. This is done with sorted with the key option:
sorted(..., key=lambda x: int(x[1]))
The key, lambda x: int(x[1]), takes the second element of the list, x[1], and converts it to an integer. In other words, sorted sorts by the integer value of the grade.
Sorting in descending order
The above sorts in ascending order. To sort in descending order, we can add the reverse=True option:
>>> sorted((line.split() for line in open('classt2.txt')), key=lambda x: int(x[1]), reverse=True)
[['Dave,', '10'], ['Lucy,', '8'], ['Jack,', '4'], ['Anne,', '3']]
Sorting while keeping the original whitespace
Sorting grades in ascending order:
>>> sorted(open('classt2.txt'), key=lambda x: int(x.split()[1]))
['Anne, 3\n', 'Jack, 4\n', 'Lucy, 8\n', 'Dave, 10\n']
To print that out nicely:
>>> print(''.join(sorted(open('classt2.txt'), key=lambda x: int(x.split()[1]))))
Anne, 3
Jack, 4
Lucy, 8
Dave, 10
来源:https://stackoverflow.com/questions/33000095/how-do-i-sort-data-highest-to-lowest-in-python-from-a-text-file