#python #list #sorting #indexing #split
Вопрос:
Я создавал программу, которая сортирует строки данных о погоде. Строки данных необходимо отсортировать по времени. Я получаю список строк погоды, которые немного отличаются друг от друга по форматированию, и в зависимости от погодных условий и того, как быстро происходят изменения, строка будет начинаться с FM
или BECMG
.
Я могу сортировать строки погоды, в которых указанное время каждый раз находится в одном и том же месте индекса (индекс [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
?? Должен ли я использовать регулярное выражение и изолировать время?? Кто-нибудь может помочь с этим, пожалуйста, я застрял?
Комментарии:
1. Поскольку существует только 2 формата, как насчет того, чтобы сначала извлечь время, а затем соответствующим образом отсортировать строку? :»)
Ответ №1:
Вы можете извлечь время с помощью регулярного выражения, а затем использовать это время в качестве «ключа» для сортировки
import re pattern = r"((?lt;=FM)d{6})|(?lt;=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']
Комментарии:
1. Это работает очень хорошо, большое вам спасибо @Ron Serruya !!!
Ответ №2:
Если строка начинается с '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'