概述:我有类似这样的数据(每行都是一个字符串):
81:0A:D7:19:25:7B, 2016-07-14 14:29:13 ,2016-07-14 14:29:15,-69,22:22 :22:22:22:23,空,^ M 3B:3F:B9:0A:83:E6, 2016-07-14 01:28:59 ,2016-07-14 01:29:01,-36,33:33:33: 33:33:31,空,^ M B3:C0:6E:77:E5:31, 2016-07-14 08:26:45 ,2016-07-14 08:26:47,-65,33:33:33: 33:33:32,空,^ M 61:01:55:16:B5:52, 2016-07-14 06:25:32 ,2016-07-14 06:25:34,-56,33:33:33: 33:33:33,空,^ M
我想根据每个String中存在的第一个时间戳对每一行进行排序,对于这四个记录是:
2016-07-14 01:28:59
2016-07-14 06:25:32
2016-07-14 08:26:45
2016-07-14 14:29:13
现在我知道了sort()
方法,但是我不明白如何在这里根据这个(时间戳)数量对所有行进行排序,我确实需要保持最终的排序数据相同格式,因为其他一些服务将使用它。
我也理解我可以制作key()
,但我不清楚如何对时间戳字段进行排序。
答案 0 :(得分:10)
您可以使用就地排序的列表方法list.sort
或使用返回新列表的sorted()
内置函数。 key
参数采用一个函数,它在排序之前应用于序列的每个元素。您可以使用string.split(',')
和索引到第二个元素的组合,例如some_list [1],所以:
In [8]: list_of_strings
Out[8]:
['81:0A:D7:19:25:7B, 2016-07-14 14:29:13, 2016-07-14 14:29:15, -69, 22:22:22:22:22:23,null,^M',
'3B:3F:B9:0A:83:E6, 2016-07-14 01:28:59, 2016-07-14 01:29:01, -36, 33:33:33:33:33:31,null,^M',
'B3:C0:6E:77:E5:31, 2016-07-14 08:26:45, 2016-07-14 08:26:47, -65, 33:33:33:33:33:32,null,^M',
'61:01:55:16:B5:52, 2016-07-14 06:25:32, 2016-07-14 06:25:34, -56, 33:33:33:33:33:33,null,^M']
In [9]: sorted(list_of_strings, key=lambda s: s.split(',')[1])
Out[9]:
['3B:3F:B9:0A:83:E6, 2016-07-14 01:28:59, 2016-07-14 01:29:01, -36, 33:33:33:33:33:31,null,^M',
'61:01:55:16:B5:52, 2016-07-14 06:25:32, 2016-07-14 06:25:34, -56, 33:33:33:33:33:33,null,^M',
'B3:C0:6E:77:E5:31, 2016-07-14 08:26:45, 2016-07-14 08:26:47, -65, 33:33:33:33:33:32,null,^M',
'81:0A:D7:19:25:7B, 2016-07-14 14:29:13, 2016-07-14 14:29:15, -69, 22:22:22:22:22:23,null,^M']
或者,如果您更愿意对列表进行排序,
list_of_strings
Out[12]:
['81:0A:D7:19:25:7B, 2016-07-14 14:29:13, 2016-07-14 14:29:15, -69, 22:22:22:22:22:23,null,^M',
'3B:3F:B9:0A:83:E6, 2016-07-14 01:28:59, 2016-07-14 01:29:01, -36, 33:33:33:33:33:31,null,^M',
'B3:C0:6E:77:E5:31, 2016-07-14 08:26:45, 2016-07-14 08:26:47, -65, 33:33:33:33:33:32,null,^M',
'61:01:55:16:B5:52, 2016-07-14 06:25:32, 2016-07-14 06:25:34, -56, 33:33:33:33:33:33,null,^M']
list_of_strings.sort(key=lambda s: s.split(',')[1])
list_of_strings
Out[14]:
['3B:3F:B9:0A:83:E6, 2016-07-14 01:28:59, 2016-07-14 01:29:01, -36, 33:33:33:33:33:31,null,^M',
'61:01:55:16:B5:52, 2016-07-14 06:25:32, 2016-07-14 06:25:34, -56, 33:33:33:33:33:33,null,^M',
'B3:C0:6E:77:E5:31, 2016-07-14 08:26:45, 2016-07-14 08:26:47, -65, 33:33:33:33:33:32,null,^M',
'81:0A:D7:19:25:7B, 2016-07-14 14:29:13, 2016-07-14 14:29:15, -69, 22:22:22:22:22:23,null,^M']
答案 1 :(得分:2)
如果不改变行本身的格式,可能(我不知道解决方案的更广泛的上下文)一个简单的shell转换很合适(我知道它不是python解决方案)。
所以:
$ sort -t, -k2,2 sort_me_on_first_timestamp_field.txt
3B:3F:B9:0A:83:E6, 2016-07-14 01:28:59, 2016-07-14 01:29:01, -36, 33:33:33:33:33:31,null,^M
61:01:55:16:B5:52, 2016-07-14 06:25:32, 2016-07-14 06:25:34, -56, 33:33:33:33:33:33,null,^M
B3:C0:6E:77:E5:31, 2016-07-14 08:26:45, 2016-07-14 08:26:47, -65, 33:33:33:33:33:32,null,^M
81:0A:D7:19:25:7B, 2016-07-14 14:29:13, 2016-07-14 14:29:15, -69, 22:22:22:22:22:23,null,^M
对我来说很好看。 -t选项告诉sort使用逗号作为分隔符,-k2,2基于第二个“字段”请求排序(它从一开始计数)。有时用-n切换到数字排序很重要,但是这里的ISO datetime字符串是固定长度的,它应该与词法排序一起使用。
再说一遍:如果你正在寻找一个纯python解决方案,我建议选择建议的基于python的答案。这只是建议一个基线替代方案。
更新以“测量”某些机器上的某些情况 - 好吧:
在“开发者的机器”上,将样本4行连续多次连接成20,200,2000,...,2,000,000行的文件,从12毫秒到1.7秒(200万行)到使用sort命令写入/ dev / null并写入文件2秒。
@ juanpa.arrivillaga建议的路线排序的原始实施:
#! /usr/bin/env python
FILE_PATH_IN = './fhf.txt'
NL, FS = '\n', ','
list_of_strings = open(FILE_PATH_IN).read().split(NL)[:-1]
list_of_strings.sort(key=lambda s: s.split(FS)[1])
with open(FILE_PATH_IN + ".out", "wt") as f:
f.write(NL.join(list_of_strings))
在同一台机器上需要大约。作为另一个变体(使用sorted来生成新列表)的200万行案例的3秒确实:
#! /usr/bin/env python
FILE_PATH_IN = './fhf.txt'
NL, FS = '\n', ','
list_of_strings = open(FILE_PATH_IN).read().split(NL)[:-1]
with open(FILE_PATH_IN + ".out", "wt") as f:
f.write(NL.join(sorted(list_of_strings, key=lambda s: s.split(',')[1])))
所以建议使用纯python解决方案。
答案 2 :(得分:1)
你可以使用string.split()
,string.split(',')[1]