如果时间位于行中的不同位置,如何按时间对列表行进行排序?
How can I sort list lines by time if the times are in different locations in the line?
我一直在制作一个对天气数据行进行排序的程序。需要按时间顺序对数据行进行排序。我收到了一份天气线列表,这些天气线的格式彼此略有不同,并且根据天气行为和变化发生的速度,该线将以 FM
或 BECMG
.[=21 开头=]
我能够对列出的时间每次都位于同一索引位置(索引 [0])的天气行进行排序。例如:
FM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010
和
FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030
从上面的两个例子来看,第一个的时间显示的是该月的第 13 天,在 12:00。在第二个中,它是该月的第 14 天 14:00。这种格式很好,因为两者的时间索引在同一索引中,但是如果我遇到如下情况,我的排序将不起作用。
FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010
和
BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030
从上面的示例来看,第一行显然与前面的示例相同,但第二行在位置(索引[1])和格式上有所不同。第二行中的时间是该月的第 13 天 15:00。
我以这个为例,说明我现在如何按时间顺序对它们进行排序,但只有当该行的时间位于索引 [0] 时才有效。
import re
total_print = ['\nBECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030', '\nFM131200 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010',
'\nFM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010']
data = {
'other': [], # anything with FM or BECMG
}
for line in total_print:
key = 'other'
data[key].append(line)
final = []
data['other'] = sorted(data['other'], key=lambda x: x.split()[0])
for lst in data.values():
for line in lst:
final.append('\n' + line[1:])
print(' '.join(final))
这些行以随机顺序提供,有时全部以 BECMG
开头或全部以 FM
开头,有时两者兼而有之。所以我需要找到一种方法来对它们进行排序,不管它们是怎么来的。
无论行是以 FM
还是 BECMG
开头,如何按时间顺序对行进行排序?我应该使用 Regex 并隔离时间吗?有人可以帮忙吗,我被卡住了?
您可以使用正则表达式提取时间,然后将此时间作为“关键字”进行排序
import re
pattern = r"((?<=FM)\d{6})|(?<=BECMG )\d{4}"
matcher = re.compile(pattern)
data = ['FM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010 ',
'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030',
'BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030',
'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010']
print(sorted(data, key=lambda item: matcher.search(item).group()))
这将打印:
['FM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010 ',
'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030',
'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010',
'BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030']
如果该行以'FM'
开头,则时间为该行的第2、3、4、5个字符。如果该行以 BECMG 开头,则时间为该行的第 6、7、8、9 个字符。
您可以将其用作排序的关键字:
data = ['\nFM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010 ',
'\nFM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030',
'\nBECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030',
'\nFM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010']
data = [s.strip() for s in data]
def sorting_key(s):
if s.startswith('FM'):
return int(s[2:4]), int(s[4:6])
elif s.startswith('BECMG'):
return int(s[6:8]), int(s[8:10])
else:
raise ValueError(''.join(['Neither FM nor BECMG: ', s]))
data = sorted(data, key=sorting_key)
print(data)
# ['FM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010',
# 'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030',
# 'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010',
# 'BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030']
当无法正确提取时间时,此代码将引发 ValueError
:
sorted(['hello'], key=sorting_key)
# ValueError: Neither FM nor BECMG: hello
sorted(['FM13hello'], key=sorting_key)
# ValueError: invalid literal for int() with base 10: 'he'
我一直在制作一个对天气数据行进行排序的程序。需要按时间顺序对数据行进行排序。我收到了一份天气线列表,这些天气线的格式彼此略有不同,并且根据天气行为和变化发生的速度,该线将以 FM
或 BECMG
.[=21 开头=]
我能够对列出的时间每次都位于同一索引位置(索引 [0])的天气行进行排序。例如:
FM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010
和
FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030
从上面的两个例子来看,第一个的时间显示的是该月的第 13 天,在 12:00。在第二个中,它是该月的第 14 天 14:00。这种格式很好,因为两者的时间索引在同一索引中,但是如果我遇到如下情况,我的排序将不起作用。
FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010
和
BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030
从上面的示例来看,第一行显然与前面的示例相同,但第二行在位置(索引[1])和格式上有所不同。第二行中的时间是该月的第 13 天 15:00。
我以这个为例,说明我现在如何按时间顺序对它们进行排序,但只有当该行的时间位于索引 [0] 时才有效。
import re
total_print = ['\nBECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030', '\nFM131200 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010',
'\nFM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010']
data = {
'other': [], # anything with FM or BECMG
}
for line in total_print:
key = 'other'
data[key].append(line)
final = []
data['other'] = sorted(data['other'], key=lambda x: x.split()[0])
for lst in data.values():
for line in lst:
final.append('\n' + line[1:])
print(' '.join(final))
这些行以随机顺序提供,有时全部以 BECMG
开头或全部以 FM
开头,有时两者兼而有之。所以我需要找到一种方法来对它们进行排序,不管它们是怎么来的。
无论行是以 FM
还是 BECMG
开头,如何按时间顺序对行进行排序?我应该使用 Regex 并隔离时间吗?有人可以帮忙吗,我被卡住了?
您可以使用正则表达式提取时间,然后将此时间作为“关键字”进行排序
import re
pattern = r"((?<=FM)\d{6})|(?<=BECMG )\d{4}"
matcher = re.compile(pattern)
data = ['FM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010 ',
'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030',
'BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030',
'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010']
print(sorted(data, key=lambda item: matcher.search(item).group()))
这将打印:
['FM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010 ',
'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030',
'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010',
'BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030']
如果该行以'FM'
开头,则时间为该行的第2、3、4、5个字符。如果该行以 BECMG 开头,则时间为该行的第 6、7、8、9 个字符。
您可以将其用作排序的关键字:
data = ['\nFM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010 ',
'\nFM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030',
'\nBECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030',
'\nFM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010']
data = [s.strip() for s in data]
def sorting_key(s):
if s.startswith('FM'):
return int(s[2:4]), int(s[4:6])
elif s.startswith('BECMG'):
return int(s[6:8]), int(s[8:10])
else:
raise ValueError(''.join(['Neither FM nor BECMG: ', s]))
data = sorted(data, key=sorting_key)
print(data)
# ['FM131200 20010KT 5000 SHOWERS OF LIGHT RAIN SCT006 BKN010',
# 'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 FEW030',
# 'FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010',
# 'BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030']
当无法正确提取时间时,此代码将引发 ValueError
:
sorted(['hello'], key=sorting_key)
# ValueError: Neither FM nor BECMG: hello
sorted(['FM13hello'], key=sorting_key)
# ValueError: invalid literal for int() with base 10: 'he'