目前我按照这样的降序对文本文件进行排序:
import operator
fo = open('3a.txt','r')
x = fo.readlines()
sorted_x = sorted(x, key=operator.itemgetter(0),reverse = True)
print(sorted_x)
我的文本文件如下所示:
5 Helen
4 judy
8 Rachel
我想知道如何将operator.itemgetter(0)
用于双数字?
当我使用它时:
5 Helen
4 judy
25 Hanna
11 Elsa
8 Rachel
结果都错了:
['8 Rachel', '5 Helen', '4 judy', '25 Hanna', '11 Elsa']
即使我使用operator.itemgetter(0, 1)
。
答案 0 :(得分:11)
你的operator.itemgetter(0)
方法只能让你到目前为止;它总是会选择你的行的
要以数字方式对文件进行正确排序,您的key
函数必须执行以下操作:
后者很重要,因为排序字符串是按字典顺序完成的;例如'10'
在'9'
之前排序,因为1
位于9
之前。
要在行的开头支持任意数字字符运行(由空格分隔),您需要拆分空白。 str.split()
method可以为您执行此操作,如果您不给它任何参数或使用None
作为第一个参数。为了保持高效,将分割数限制为1,并将结果的第一个元素转换为整数:
fo = open('3a.txt','r')
x = fo.readlines()
sort_key = lambda line: int(line.split(None, 1)[0])
sorted_x = sorted(x, key=sort_key, reverse=True)
print(sorted_x)
因此key
参数被赋予一个匿名函数(lambda
),该函数接受一个参数,该行被排序。该行仅在空格上拆分一次(line.split(None, 1)
,并且该拆分的第一个元素变为整数:
>>> '11 Hello World'.split(None, 1)
['11', 'Hello World']
>>> '11 Hello World'.split(None, 1)[0]
'11'
>>> int('11 Hello World'.split(None, 1)[0])
11
您也可以改进其余的实施;由于文件是可迭代的,因此无需调用file.readlines()
。 sorted()
将把所有内容都放在一个可迭代的中并对其进行排序,这样你就可以将整个文件对象直接传递给函数。
您还希望处理文件,以便在完成后自动关闭它们。利用他们是上下文管理者的事实;当上下文“完成”(已结束)并且文件对象将自动关闭时,with
语句将向它们发出信号:
sort_key = lambda line: int(line.split(None, 1)[0])
with open('3a.txt','r') as fo:
sorted_x = sorted(fo, key=sort_key, reverse=True)
print(sorted_x)
演示:
>>> from io import StringIO
>>> fo = StringIO('''\
... 5 Helen
... 4 judy
... 25 Hanna
... 11 Elsa
... 8 Rachel
... '''
... )
>>> sort_key = lambda line: int(line.split(None, 1)[0])
>>> sorted(fo, key=sort_key, reverse=True)
['25 Hanna\n', '11 Elsa\n', '8 Rachel\n', '5 Helen \n', '4 judy\n']
只有当您首先将行拆分为列表时,您才能完成此操作且仍然使用operator.itemgetter(0)
,其中元素0
是整数:
import operator
sort_key = operator.itemgetter(0)
with open('3a.txt','r') as fo:
split_lines = (line.split(None, 1) for line in fo)
numeric_lines = ((int(line[0]), line[1]) for line in split_lines)
sorted_x = sorted(numeric_lines, key=sort_key, reverse=True)
print(sorted_x)
这使用生成器表达式来处理正在读取的行。但是现在你有一个列表,每个元素都有一个元组,一个整数和你的其余部分:
>>> import operator
>>> fo = StringIO('''\
... 5 Helen
... 4 judy
... 25 Hanna
... 11 Elsa
... 8 Rachel
... ''')
>>> sort_key = operator.itemgetter(0)
>>> split_lines = (line.split(None, 1) for line in fo)
>>> numeric_lines = ((int(line[0]), line[1]) for line in split_lines)
>>> sorted(numeric_lines, key=sort_key, reverse=True)
[(25, 'Hanna\n'), (11, 'Elsa\n'), (8, 'Rachel\n'), (5, 'Helen \n'), (4, 'judy\n')]