【发布时间】:2021-12-19 05:05:15
【问题描述】:
我正在开发一个解析天气信息的程序。在我的这部分代码中,我试图按时间顺序重新组织结果,然后再继续附加更多项目。
这些行中的时间通常是任何一行的前 4 位数字(前 2 位数字是日期,其他数字是小时)。例外情况是以11010KT 开头的行,该行始终假定为任何天气报告中的第一行,并且这些数字是风矢量而不是时间。
您会看到我正在删除在此示例开头的任何包含 TEMPO INTER 或 PROB 的行,因为我希望将包含这些单词的行添加到另一个重组列表的末尾。这些行可以被认为是一个单独的列表,我希望按照与其他项目相同的方式按时间组织其中。
我正在尝试使用正则表达式从删除 TEMPO INTER 和 PROB 行后剩余的行中提取时间,然后对它们进行排序,然后排序后,再次使用正则表达式完整地找到该行并创建一个重组列表。完成该列表后,我将对 TEMPO INTER 和 PROB 列表进行排序,然后将其附加到我刚刚制作的新完成列表中。
我还尝试了一个for 循环,该循环将删除添加的所有重复行,但这似乎只删除了TEMPO 行的一个重复项???
有人可以帮我解决这个问题吗?我是新手,谢谢...
理想情况下,它应该看起来像这样:
ETA IS 0230 which is 1430 local
11010KT 5000 MODERATE DRIZZLE BKN004
FM050200 12012KT 9999 LIGHT DRIZZLE BKN008
TEMPO 0501/0502 2000 MODERATE DRIZZLE BKN002
INTER 0502/0506 4000 SHOWERS OF MODERATE RAIN BKN008
而不是这个,我得到以FM050200 开头的行的重复,然后重复以TEMPO 开头的行。它也没有找到以INTER 开头的行...
我制作了一个可重复的最小示例,供任何人尝试帮助我。我将在此处包括:
import re
total_print = ['\nFM050200 12012KT 9999 LIGHT DRIZZLE BKN008', '\n11010KT 5000 MODERATE DRIZZLE BKN004', '\nINTER 0502/0506 4000 SHOWERS OF MODERATE RAIN BKN008', '\nTEMPO 0501/0502 2000 MODERATE DRIZZLE BKN002']
removed_lines = []
for a in total_print: # finding and removing lines with reference to TEMPO INTER PROB
if 'TEMPO' in a:
total_print.remove(a)
removed_lines.append(a)
for b in total_print:
if 'INTER' in b:
total_print.remove(b)
removed_lines.append(b)
for f in total_print:
if 'PROB' in f:
total_print.remove(f)
removed_lines.append(f)
list_time_in_line = []
for line in total_print: # finding the times in the remaining lines
time_in_line = re.search(r'\d\d\d\d', line)
list_time_in_line.append(time_in_line.group())
sorted_time_list = sorted(list_time_in_line)
removed_time_in_line = []
for g in removed_lines: # finding the times in the lines that were originally removed
removed_times = re.search(r'\d\d\d\d', g)
removed_time_in_line.append(removed_times.group())
sorted_removed_time_list = sorted(removed_time_in_line)
final = []
final.append('ETA IS 1230 which is 1430 local\n') # appending the time display
search_for_first_line = re.search(r'[\n]\d\d\d\d\dKT', ' '.join(total_print)) # searching for line that has wind vector instead of time
search_for_first_line = search_for_first_line.group()
if search_for_first_line: # adding wind vector line so that its the firs line listed in the group
search_for_first_line = re.search(r'%s.*' % search_for_first_line, ' '.join(total_print)).group()
final.append('\n' + search_for_first_line)
print(sorted_time_list) # the list of possible times found (the second item in list is the wind vector and not a time)
d = 0
for c in sorted_time_list: # finding the whole line for the corresponding time
print(sorted_time_list[d])
search_for_whole_line = re.search(r'.*\w+\s*%s.*' % sorted_time_list[d], ' '.join(total_print))
print(search_for_whole_line.group()) # it is doubling up on the 0502 time???????
d += 1
final.append('\n' + str(search_for_whole_line.group()))
h = 0
for i in sorted_removed_time_list: # finding the whole line for the corresponding times from the previously removed items
whole_line_in_removed_srch = re.search(r'.*%s.*' % sorted_removed_time_list[h], ' '.join(removed_lines))
h += 1
final.append('\n' + str(whole_line_in_removed_srch.group())) # appending them
l_new = []
for item in final: # this doesn't seeem to properly remove duplicates ?????
if item not in l_new:
l_new.append(item)
total_print = l_new
print(' '.join(total_print))
///////////////////////////////////编辑:
我最近问过这个问题,并从@diggusbickus 那里得到了一个很好的答案。我现在在答案中的排序方面遇到了一个新问题。
因为我最初的问题在我的data['other'] 中只有一种天气线(以字母“FM”开头),所以带有split() 的lambda 只查看@987654341 行的第一项@时间。
data['other'] = sorted(data['other'], key=lambda x: x.split()[0])
时间所在的位置(在前面的问题中是FM050200,其中 05 是日期,0200 是时间)。当有以FM 开头的行时,这非常有效,但我意识到偶尔会存在这样的行:
'\nBECMG 0519/0520 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030'
这种风格的时间是位于索引 [1] 的前 4 位数字,并且采用 4 位格式而不是 FM050200 中的 6 位格式行。这条新行中的时间是 05 作为日期,19 作为小时(所以 1900)。
我需要将这种风格的线条与FM 线条组合在一起,问题是它们没有排序。我正在尝试找到一种能够按时间对行进行排序的方法,无论时间是在 [0] 索引和 6 位格式还是在 [1] 索引和 4 位格式。
我将包含一个新示例,其中对最初回答的问题进行了一些小改动。这个新问题将具有与 total_print 变量不同的数据。这是一个工作示例。
我基本上需要按任何行的前 4 位对行进行排序,结果应该如下所示:
ETA IS 0230 which is 1430 local
FM131200 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010
FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010
BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030
TEMPO 1312/1320 4000 SHOWERS OF MODERATE RAIN BKN007
注意。 TEMPO 应该放在最后,所以不用担心那个。
这是示例,非常感谢任何提供帮助的人。
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','\nTEMPO 1312/1320 4000 SHOWERS OF MODERATE RAIN BKN007']
data = {
'windvector': [], # if it is the first line of the TAF
'other': [], # anythin with FM or BECMG
'tip': [] # tempo/inter/prob
}
wind_vector = re.compile('^\s\d{5}KT')
for line in total_print:
if 'TEMPO' in line \
or 'INTER' in line \
or 'PROB' in line:
key = 'tip'
elif re.match(wind_vector, line):
key = 'windvector'
else:
key = 'other'
data[key].append(line)
final = []
data['other'] = sorted(data['other'], key=lambda x: x.split()[0])
data['tip'] = sorted(data['tip'], key=lambda x: x.split()[1])
final.append('ETA IS 0230 which is 1430 local\n')
for lst in data.values():
for line in lst:
final.append('\n' + line[1:]) # get rid of newline
print(' '.join(final))
【问题讨论】:
-
那肯定不像 MRE。在任何情况下,你都不应该从你正在迭代的东西中删除项目。
-
那么你会怎么做呢?那你能帮忙提供一个解决方案吗?
标签: python regex duplicates append re