Как я могу отсортировать строки списка по времени, если время находится в разных местах строки?

#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'