Python 如何在v2.3中按第n个元素对列表排序?
这是我写的一个简单脚本:Python 如何在v2.3中按第n个元素对列表排序?,python,Python,这是我写的一个简单脚本: #!/usr/bin/env python file = open('readFile.txt', 'r') lines = file.readlines() file.close() del file sortedList = sorted(lines, key=lambda lines: lines.split('\t')[-2]) file = open('outfile.txt', 'w') for line in sortedList: file
#!/usr/bin/env python
file = open('readFile.txt', 'r')
lines = file.readlines()
file.close()
del file
sortedList = sorted(lines, key=lambda lines: lines.split('\t')[-2])
file = open('outfile.txt', 'w')
for line in sortedList:
file.write(line)
file.close()
del file
要像这样重写文件,请执行以下操作:
161788 group_monitor.sgmops 4530 1293840320 1293840152
161789 group_atlas.atlas053 22350 1293840262 1293840152
161790 group_alice.alice017 210 1293840254 1293840159
161791 group_lhcb.pltlhc15 108277 1293949235 1293840159
161792 group_atlas.sgmatlas 35349 1293840251 1293840160
161792 group_atlas.sgmatlas 35349 01/01/11 00:04:11 01/01/11 00:02:40
161790 group_alice.alice017 210 01/01/11 00:04:14 01/01/11 00:02:39
161789 group_atlas.atlas053 22350 01/01/11 00:04:22 01/01/11 00:02:32
def format_seconds_since_epoch(t):
if t == 3600:
return "aborted"
else:
return strftime("%d/%m/%y %H:%M:%S",datetime.fromtimestamp(t).timetuple())
(其中最后两个字段为历元时间)由下一个到最后一个字段排序:
161792 group_atlas.sgmatlas 35349 1293840251 1293840160
161790 group_alice.alice017 210 1293840254 1293840159
161789 group_atlas.atlas053 22350 1293840262 1293840152
161788 group_monitor.sgmops 4530 1293840320 1293840152
161791 group_lhcb.pltlhc15 108277 1293949235 1293840159
如您所见,我使用了v2.4中引入的sorted()
,如何重写v2.3的脚本,以使其执行相同的操作。
此外,我想将历元时间转换为人类可读的格式,因此生成的文件如下所示:
161788 group_monitor.sgmops 4530 1293840320 1293840152
161789 group_atlas.atlas053 22350 1293840262 1293840152
161790 group_alice.alice017 210 1293840254 1293840159
161791 group_lhcb.pltlhc15 108277 1293949235 1293840159
161792 group_atlas.sgmatlas 35349 1293840251 1293840160
161792 group_atlas.sgmatlas 35349 01/01/11 00:04:11 01/01/11 00:02:40
161790 group_alice.alice017 210 01/01/11 00:04:14 01/01/11 00:02:39
161789 group_atlas.atlas053 22350 01/01/11 00:04:22 01/01/11 00:02:32
def format_seconds_since_epoch(t):
if t == 3600:
return "aborted"
else:
return strftime("%d/%m/%y %H:%M:%S",datetime.fromtimestamp(t).timetuple())
我知道,这个strftime(“%d/%m/%y%H:%m:%S”,gmtime())
可以用来转换历元时间,但我不知道如何将它应用到脚本中,以那种格式重写文件
评论?宝贵的忠告!
@Mark:Update 在某些情况下,大纪元时间为
3600
,表示未完成的业务。我想为这样一行打印中止,而不是01/01/1970
。因此,我更改了格式\u seconds\u,因为\u epoch()
如下:
161788 group_monitor.sgmops 4530 1293840320 1293840152
161789 group_atlas.atlas053 22350 1293840262 1293840152
161790 group_alice.alice017 210 1293840254 1293840159
161791 group_lhcb.pltlhc15 108277 1293949235 1293840159
161792 group_atlas.sgmatlas 35349 1293840251 1293840160
161792 group_atlas.sgmatlas 35349 01/01/11 00:04:11 01/01/11 00:02:40
161790 group_alice.alice017 210 01/01/11 00:04:14 01/01/11 00:02:39
161789 group_atlas.atlas053 22350 01/01/11 00:04:22 01/01/11 00:02:32
def format_seconds_since_epoch(t):
if t == 3600:
return "aborted"
else:
return strftime("%d/%m/%y %H:%M:%S",datetime.fromtimestamp(t).timetuple())
解决了问题。在这方面,这是最好的做法吗?干杯 在回答您的最终查询时,您可以使用
datetime从time\t
创建一个datetime
对象,例如使用datetime.fromtimestamp
,从“自历元起的秒数”值
file = open('readFile.txt', 'r')
lines = file.readlines()
file.close()
del file
lines = [line.split(' ') for line in lines]
lines.sort(lambda x,y: cmp(x[2], y[2])
lines = [' '.join(line) for line in lines]
from datetime import datetime
from time import strftime
def format_seconds_since_epoch(t):
return strftime("%d/%m/%y %H:%M:%S",datetime.fromtimestamp(t).timetuple())
print format_seconds_since_epoch(1293840160)
因此,将其与稍加修改的版本结合起来,您的脚本可能如下所示:
#!/usr/bin/env python
from datetime import datetime
from time import strftime
import os
def format_seconds_since_epoch(t):
return strftime("%d/%m/%y %H:%M:%S",datetime.fromtimestamp(t).timetuple())
fin = open('readFile.txt', 'r')
lines = fin.readlines()
fin.close()
del fin
split_lines = [ line.split("\t") for line in lines ]
split_lines.sort( lambda a, b: cmp(int(a[-2]),int(b[-2])) )
fout = open('outfile.txt', 'w')
for split_line in split_lines:
for i in (-2,-1):
split_line[i] = format_seconds_since_epoch(int(split_line[i]))
fout.write("\t".join(split_line)+os.linesep)
fout.close()
del fout
请注意,使用file
作为变量名是个坏主意,因为它会隐藏内置的file
类型,所以我将它们更改为fin
和fout
。(我认为,即使您在del
ing变量之后,避免使用file
这个名称仍然是一种很好的方式。)
在回答关于特殊“3600”值的进一步问题时,您的解决方案很好。就我个人而言,我可能会保留format\u seconds\u-since\u epoch
函数的原样,这样它就不会有令人惊讶的特殊情况,并且更普遍地有用。您可以使用特殊情况创建一个额外的包装函数,或者只需将split\u line[i]=format\u seconds\u since\u epoch(int(split\u line[i]))
行更改为:
entry = int(split_line[i])
if entry == 3600:
split_line[i] = "aborted"
else:
split_line[i] = format_seconds_since_epoch(entry)
。。。然而,我不认为有什么不同
顺便说一句,如果这不仅仅是一项一次性任务,我想看看你是否可以在2系列中使用比2.3更高版本的Python,现在已经相当旧了——它们有很多很好的特性,可以帮助你编写更干净的脚本。在回答你的最后一个查询时,你可以从时间创建对象,比如使用datetime.fromtimestamp
的“自历元起的秒数”值,例如
from datetime import datetime
from time import strftime
def format_seconds_since_epoch(t):
return strftime("%d/%m/%y %H:%M:%S",datetime.fromtimestamp(t).timetuple())
print format_seconds_since_epoch(1293840160)
因此,将其与稍加修改的版本结合起来,您的脚本可能如下所示:
#!/usr/bin/env python
from datetime import datetime
from time import strftime
import os
def format_seconds_since_epoch(t):
return strftime("%d/%m/%y %H:%M:%S",datetime.fromtimestamp(t).timetuple())
fin = open('readFile.txt', 'r')
lines = fin.readlines()
fin.close()
del fin
split_lines = [ line.split("\t") for line in lines ]
split_lines.sort( lambda a, b: cmp(int(a[-2]),int(b[-2])) )
fout = open('outfile.txt', 'w')
for split_line in split_lines:
for i in (-2,-1):
split_line[i] = format_seconds_since_epoch(int(split_line[i]))
fout.write("\t".join(split_line)+os.linesep)
fout.close()
del fout
请注意,使用文件
作为变量名是个坏主意,因为它会隐藏内置的文件
类型,所以我将它们更改为fin
和fout
(即使您在之后删除变量,我认为避免使用文件
名称仍然是一种很好的方式。)
在回答您关于“3600”特别版的进一步问题时“值,您的解决方案很好。就我个人而言,我可能会保留format\u seconds\u-since\u epoch
函数的原样,这样它就不会有令人惊讶的特殊情况,并且更普遍地有用。您可以使用特殊情况创建一个额外的包装函数,或者只需将split\u line[i]=format\u seconds\u since\u epoch(int(split\u line[i]))
行更改为:
entry = int(split_line[i])
if entry == 3600:
split_line[i] = "aborted"
else:
split_line[i] = format_seconds_since_epoch(entry)
。。。然而,我不认为有什么不同
顺便说一句,如果这不仅仅是一项一次性任务,我想看看您是否可以在2系列中使用比2.3更高版本的Python,而2.3现在已经相当旧了-它们有很多很好的功能,可以帮助您编写更干净的脚本。一些小事情:1。OP的文件由选项卡分隔,而不是单个空格2。您需要比较最后第二列,而不是第三列3。可能最好在比较之前将列值转换为数字,以防某些值是2001年9月之前的倍:)一些小事情:1。OP的文件由选项卡分隔,而不是单个空格2。您需要比较最后第二列,而不是第三列3。可能最好在比较之前将列值转换为数字,以防某些值是2001年9月之前的倍:)@mark:非常感谢。稍后我将测试脚本(生成实际的输入文件需要一点时间),并很快在这里报告。是的,使用文件
作为变量名是个坏主意,我确实犯了错误。谢谢你指出。干杯@马克:效果非常好。谢谢你的快速重播。干杯@马克:嗯,有一个小问题:有时候,最后一个字段显示为“3600”,这意味着某项工作没有成功完成。对于这样的行,如何打印例如“中止”而不是01/01/70 02:00:00
?干杯@马克:我已经解决了“3600”问题,修改了格式\u seconds\u since\u epoch()函数;更新了我原来的帖子。不确定这是不是最好的方法。干杯@MacUsers:没问题-我已经用另一个建议更新了我的答案,但是你的答案看起来不错。(我还将元组中的索引改为-2,-1,而不是3,4,因为你说它们总是最后两列。)@mark:非常感谢。稍后我将测试脚本(生成实际的输入文件需要一点时间),并很快在这里报告。是的,使用文件
作为变量名是个坏主意,我确实犯了错误。谢谢你指出。干杯@马克:效果非常好。谢谢你的快速重播。干杯@马克:嗯,有一个小问题:有时候,最后一个字段显示为“3600”,这意味着某项工作没有成功完成。对于这样的行,如何打印例如“中止”而不是01/01/70 02:00:00
?干杯