Python实现缺失信号字符串的范围化日志输出优化
合并同前缀末尾数字连续的缺失信号字符串
问题背景
有一个记录未找到信号的字符串列表missing_signals,信号编号范围可能超过600个,直接打印会生成大量冗余日志行。需要实现以下合并规则:
- 仅合并同前缀、仅末尾最后一组数字有差异的信号(比如
signal1到signal1000合并为signal1...1000) - 若字符串包含多组数字,仅处理最后一组(比如
temp_sensor_2_10、temp_sensor_2_11合并为temp_sensor_2_10...11,不处理中间的数字2) - 现有代码输出不符合预期,需要更简洁的Pythonic实现方式
解决方案
可以通过正则拆分前缀与末尾数字,结合分组和连续序列合并实现,代码如下:
import re from itertools import groupby def merge_missing_signals(signals): # 正则匹配:捕获前缀(最后一组数字前的所有内容)和末尾数字 pattern = re.compile(r'(.*?)(\d+)$') parsed = [] for sig in signals: match = pattern.match(sig) if match: prefix, num_str = match.groups() parsed.append((prefix, int(num_str), sig)) else: # 无末尾数字的项直接标记 parsed.append((sig, None, sig)) # 按前缀排序分组,无数字的项统一放最后 parsed_sorted = sorted(parsed, key=lambda x: (x[0], x[1] if x[1] is not None else float('inf'))) merged = [] for prefix, group in groupby(parsed_sorted, key=lambda x: x[0]): group_items = list(group) # 处理无末尾数字的信号 if group_items[0][1] is None: merged.extend(item[2] for item in group_items) continue # 提取组内数字,合并连续序列 nums = [item[1] for item in group_items] start = end = nums[0] for num in nums[1:]: if num == end + 1: end = num else: merged.append(f"{prefix}{start}...{end}" if start != end else f"{prefix}{start}") start = end = num # 处理最后一个序列 merged.append(f"{prefix}{start}...{end}" if start != end else f"{prefix}{start}") return merged # 示例测试 if __name__ == "__main__": test_signals = [ "signal1", "signal2", "signal3", "signal5", "temp_sensor_3_10", "temp_sensor_3_11", "temp_sensor_3_13", "light_sensor", "light_sensor" ] print(merge_missing_signals(test_signals)) # 输出:['signal1...3', 'signal5', 'temp_sensor_3_10...11', 'temp_sensor_3_13', 'light_sensor', 'light_sensor']
代码说明
- 正则解析:用
(.*?)(\d+)$精准定位最后一组数字,将每个信号拆分为前缀、数字值、原字符串三个部分,无数字项单独标记 - 排序分组:按前缀和数字排序后,用
itertools.groupby按前缀分组,确保同类型信号归为一组 - 连续序列合并:遍历组内数字,判断是否连续,将连续区间合并为
前缀起始...结束格式,非连续项单独保留 - 兼容性处理:直接保留无末尾数字的信号,重复项也会保留(如需去重可在解析前转集合再转回列表)
内容的提问来源于stack exchange,提问作者Andrei M.
相关产品推荐
相关产品推荐

