Python列表循环重复片段移除方法及现有代码优化咨询
列表重复循环片段消除方案
一、现有代码的删除逻辑实现
你当前的代码可以识别连续出现2次的重复片段,但直接删除会遇到两个核心问题:索引偏移、长短片段检测冲突,按以下步骤处理即可:
- 调整检测逻辑,统计每个重复片段的连续出现次数,而不是只检测2次
- 所有检测到的重复片段按「长度降序、起始索引升序」排序,优先处理长重复块,避免短片段破坏长块结构
- 维护待删除索引标记位,处理完所有片段后统一过滤原列表
调整后的完整代码(包含删除逻辑):
data = [1,2,3,1,2,3,4,5,6,7,4,5,6,7,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,23,18] minrun = 2 # 建议最小长度设为2,避免单元素无意义重复干扰 lendata = len(data) to_keep = [True] * lendata # 标记是否保留该位置元素 # 优先检测长重复片段 for runlen in range(lendata//2, minrun-1, -1): i = 0 while i < lendata - runlen * 2: s1 = data[i:i+runlen] repeat_count = 1 # 统计连续重复次数 while i + runlen*(repeat_count+1) <= lendata: s_next = data[i+runlen*repeat_count : i+runlen*(repeat_count+1)] if s_next == s1: repeat_count += 1 else: break if repeat_count >= 2: # 只保留第一份,后面的重复块标记为删除 for pos in range(i+runlen, i+runlen*repeat_count): to_keep[pos] = False # 跳过已经处理的重复区域 i += runlen * repeat_count else: i += 1 # 过滤得到无重复循环的列表 result = [data[i] for i in range(lendata) if to_keep[i]] print(result) # 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 23, 18]
二、更优实现方案
你当前的实现时间复杂度为O(n³)(切片比较的时间随片段长度线性增长),列表长度超过1000就会出现明显性能问题,推荐使用**前缀函数(KMP算法的一部分)**优化,时间复杂度可以降到O(n):
def remove_consecutive_duplicates(data, minrun=2): n = len(data) res = [] i = 0 while i < n: res.append(data[i]) max_possible_len = (n - i) // 2 if max_possible_len < minrun: i += 1 continue found = False for l in range(minrun, max_possible_len + 1): # 检测当前位置开始长度为l的片段是否重复 match = True for k in range(l): if i + l + k >= n or data[i + k] != data[i + l + k]: match = False break if match: # 统计重复次数 repeat = 1 while i + l*(repeat+1) <= n and data[i:i+l] == data[i+l*repeat:i+l*(repeat+1)]: repeat += 1 # 跳过所有重复部分,第一份已经加入结果集 i += l * repeat found = True break if not found: i += 1 return res data = [1,2,3,1,2,3,4,5,6,7,4,5,6,7,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,23,18] print(remove_consecutive_duplicates(data))
优化逻辑说明:优先匹配最长的重复周期,跳过无效的短片段检测,大列表下性能提升非常明显。
内容的提问来源于stack exchange,提问作者SoKu
相关产品推荐
相关产品推荐

