如何从文本文件中将 Python 中的数据从高到低排序?
How do I sort data highest to lowest in Python from a text file?
我尝试了多种方法,但 none 似乎有效
答案按字母顺序出现
f=open("class2.txt", "r")
scores=myfile.readlines()
print(sorted(scores))
f.close()
['Anne, 3\n', 'Dave, 10', 'Jack, 4\n', 'Lucy, 8\n']
还有什么方法可以在转到 shell 时去掉“/n”?
根据输入和输出,我猜您正在尝试按关联值对输入名称进行排序。要按数字排序,您可以解析所有值对,或者使用 key
函数和 sorted
为您完成(无需将结果存储在任何地方)。例如:
# 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")
print(sorted(stripnewlines, reverse=True, key=getlinevalue))
的输出将是(模一些白色space;屏幕截图很难判断逗号后有多少白色space,所以我只是使用单个 space):
['Dave, 10', 'Lucy, 8', 'Jack, 4', 'Anne, 3']
这就是你想要的。
评论中要求的代码说明:
- 在
getlinevalue
中,我们将提供的字符串拆分为白色 space(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 to intpart
as '10'
. Then we convert the string '10'
to its integer value with int()
和 return it
with open("classt2.txt") as f:
打开文件进行读取,并将结果赋值给f
;当缩进的 with
block 完成时,文件将为您关闭(即使该块由于异常或 return 从函数退出)
stripnewlines = (line.rstrip() for line in f)
创建一个 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()
以删除所有尾随的白色 space(例如新行;您可以使用 str.rstrip("\r\n")
仅删除换行符,而不删除尾随制表符或 spaces,但需要调整 key
函数)。我们可以使用列表推导式而不是生成器表达式,但是由于 sorted
无论如何都会为我们创建 list
,我们懒得避免同时存储已排序和未排序的列表(或者,列表理解之后可以对结果进行 .sort(...)
调用,这也可以避免在内存中保留两个列表,但是 .sort(...)
不会 return 任何东西,所以我们' d 有更多的代码行)。
sorted(stripnewlines, reverse=True, key=getlinevalue)
就像您在尝试中使用的 sorted
一样,只是它根据调用 getlinevalue
的结果对每个(rstrip
-ed)行进行排序它(每个值只调用一次 key
函数,这就是 key
优于 cmp
的原因;cmp
必须将每个值转换 log(n)
次在排序过程中,平均总计 n log(n)
次转换;key
转换每个值一次,并执行总共 n
次转换)。因此,它通过比较调用 getlinevalue('Dave, 10')
(10
) 与 getlinevalue('Anne, 3')
(3
) 的结果,对 'Dave, 10'
相对于 'Anne, 3'
进行排序。由于数字通常按升序(从低到高)排序(因此 3
会在 10
之前排序)并且您想要降序(从高到低)我们还传递 reverse=True
来反转 "natural" 整数排序。
- 最后一行代码使用 "splat" 运算符 (
*
) 将 sorted
调用产生的列表转换为 sequential positional arguments to print
; for Python 3's print
function(或 print
function you get in Python 2 with from __future__ import print_function
that replaces the normal print
statement of Py2), each argument is printed, with sep
printed between each argument (defaults to单个 space、' '
),当所有参数都打印出来时,在它后面跟上 end
的值(默认换行,"\n"
)。这样一来,您就可以在单独的输出行上从最高到最低打印输入行,而不是在一行上打印排序列表的表示形式。
按年级排序:
>>> sorted((line.split() for line in open('classt2.txt')), key=lambda x: int(x[1]))
[['Anne,', '3'], ['Jack,', '4'], ['Lucy,', '8'], ['Dave,', '10']]
工作原理
以上代码分为两部分。第一个读取文件并拆分行:
>>> [line.split() for line in open('class')]
[['Anne,', '3'], ['Dave,', '10'], ['Jack,', '4'], ['Lucy,', '8']]
这些行未排序。
下一步是对行进行排序。这是通过 sorted
和 key
选项完成的:
sorted(..., key=lambda x: int(x[1]))
键 lambda x: int(x[1])
获取列表的第二个元素 x[1]
,并将其转换为整数。换句话说,sorted
按成绩的整数值排序。
降序排列
以上按升序排列。要按降序排序,我们可以添加 reverse=True
选项:
>>> 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']]
在保持原始空白的同时进行排序
按升序排列成绩:
>>> sorted(open('classt2.txt'), key=lambda x: int(x.split()[1]))
['Anne, 3\n', 'Jack, 4\n', 'Lucy, 8\n', 'Dave, 10\n']
要很好地打印出来:
>>> print(''.join(sorted(open('classt2.txt'), key=lambda x: int(x.split()[1]))))
Anne, 3
Jack, 4
Lucy, 8
Dave, 10
我尝试了多种方法,但 none 似乎有效 答案按字母顺序出现
f=open("class2.txt", "r")
scores=myfile.readlines()
print(sorted(scores))
f.close()
['Anne, 3\n', 'Dave, 10', 'Jack, 4\n', 'Lucy, 8\n']
还有什么方法可以在转到 shell 时去掉“/n”?
根据输入和输出,我猜您正在尝试按关联值对输入名称进行排序。要按数字排序,您可以解析所有值对,或者使用 key
函数和 sorted
为您完成(无需将结果存储在任何地方)。例如:
# 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")
print(sorted(stripnewlines, reverse=True, key=getlinevalue))
的输出将是(模一些白色space;屏幕截图很难判断逗号后有多少白色space,所以我只是使用单个 space):
['Dave, 10', 'Lucy, 8', 'Jack, 4', 'Anne, 3']
这就是你想要的。
评论中要求的代码说明:
- 在
getlinevalue
中,我们将提供的字符串拆分为白色 space(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 tointpart
as'10'
. Then we convert the string'10'
to its integer value withint()
和 return it with open("classt2.txt") as f:
打开文件进行读取,并将结果赋值给f
;当缩进的with
block 完成时,文件将为您关闭(即使该块由于异常或 return 从函数退出)stripnewlines = (line.rstrip() for line in f)
创建一个 generator expression (sort of like a lazily evaluated list comprehension that can only be iterated once) that reads a line at a time and usesstr.rstrip()
以删除所有尾随的白色 space(例如新行;您可以使用str.rstrip("\r\n")
仅删除换行符,而不删除尾随制表符或 spaces,但需要调整key
函数)。我们可以使用列表推导式而不是生成器表达式,但是由于sorted
无论如何都会为我们创建list
,我们懒得避免同时存储已排序和未排序的列表(或者,列表理解之后可以对结果进行.sort(...)
调用,这也可以避免在内存中保留两个列表,但是.sort(...)
不会 return 任何东西,所以我们' d 有更多的代码行)。sorted(stripnewlines, reverse=True, key=getlinevalue)
就像您在尝试中使用的sorted
一样,只是它根据调用getlinevalue
的结果对每个(rstrip
-ed)行进行排序它(每个值只调用一次key
函数,这就是key
优于cmp
的原因;cmp
必须将每个值转换log(n)
次在排序过程中,平均总计n log(n)
次转换;key
转换每个值一次,并执行总共n
次转换)。因此,它通过比较调用getlinevalue('Dave, 10')
(10
) 与getlinevalue('Anne, 3')
(3
) 的结果,对'Dave, 10'
相对于'Anne, 3'
进行排序。由于数字通常按升序(从低到高)排序(因此3
会在10
之前排序)并且您想要降序(从高到低)我们还传递reverse=True
来反转 "natural" 整数排序。- 最后一行代码使用 "splat" 运算符 (
*
) 将sorted
调用产生的列表转换为 sequential positional arguments toprint
; for Python 3'sprint
function(或print
function you get in Python 2 withfrom __future__ import print_function
that replaces the normalprint
statement of Py2), each argument is printed, withsep
printed between each argument (defaults to单个 space、' '
),当所有参数都打印出来时,在它后面跟上end
的值(默认换行,"\n"
)。这样一来,您就可以在单独的输出行上从最高到最低打印输入行,而不是在一行上打印排序列表的表示形式。
按年级排序:
>>> sorted((line.split() for line in open('classt2.txt')), key=lambda x: int(x[1]))
[['Anne,', '3'], ['Jack,', '4'], ['Lucy,', '8'], ['Dave,', '10']]
工作原理
以上代码分为两部分。第一个读取文件并拆分行:
>>> [line.split() for line in open('class')]
[['Anne,', '3'], ['Dave,', '10'], ['Jack,', '4'], ['Lucy,', '8']]
这些行未排序。
下一步是对行进行排序。这是通过 sorted
和 key
选项完成的:
sorted(..., key=lambda x: int(x[1]))
键 lambda x: int(x[1])
获取列表的第二个元素 x[1]
,并将其转换为整数。换句话说,sorted
按成绩的整数值排序。
降序排列
以上按升序排列。要按降序排序,我们可以添加 reverse=True
选项:
>>> 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']]
在保持原始空白的同时进行排序
按升序排列成绩:
>>> sorted(open('classt2.txt'), key=lambda x: int(x.split()[1]))
['Anne, 3\n', 'Jack, 4\n', 'Lucy, 8\n', 'Dave, 10\n']
要很好地打印出来:
>>> print(''.join(sorted(open('classt2.txt'), key=lambda x: int(x.split()[1]))))
Anne, 3
Jack, 4
Lucy, 8
Dave, 10