如何优化Python子串统计代码,使其更高效更简洁?
代码优化方案
你的原代码逻辑是统计所有索引不同的字符串对(i,j)中满足strings[j]是strings[i]子串的总数量,我们可以从整洁性和效率两个维度做优化:
1. 小数据量场景:优先整洁可读
如果你的字符串数量不多(一般少于1000),优先保证代码简洁易维护,优化后代码如下:
from itertools import product strings = [input("String: ") for _ in range(int(input("How many strings?")))] count = sum(1 for i, j in product(range(len(strings)), repeat=2) if i != j and strings[j] in strings[i]) print(f"There are {count} substrings")
整洁优化点:
- 用
itertools.product替代两层嵌套for循环,减少缩进层级,逻辑更清晰 - 循环中不需要用到的计数变量用
_代替,明确语义 - 用生成器表达式+
sum直接计数,省略手动初始化计数变量再累加的冗余步骤 - 用f-string做输出格式化,比逗号拼接的写法更易读
2. 大数据量场景:优先运行效率
如果字符串数量很大,原代码O(n²*L)的时间复杂度会有明显性能问题,可以按如下逻辑优化:
from collections import defaultdict n = int(input("How many strings?")) strings = [input("String: ") for _ in range(n)] # 按字符串长度分组统计相同字符串的出现次数 len_map = defaultdict(lambda: defaultdict(int)) for s in strings: len_map[len(s)][s] += 1 count = 0 for cur_s in strings: cur_len = len(cur_s) # 子串长度不可能超过母串,只遍历长度小于等于当前字符串的分组 for check_len in range(1, cur_len + 1): if check_len not in len_map: continue for check_s, cnt in len_map[check_len].items(): if check_s in cur_s: if check_len == cur_len and check_s == cur_s: # 长度相等时要排除当前字符串自身的计数 count += cnt - 1 else: count += cnt print(f"There are {count} substrings")
效率优化点:
- 砍掉无效比较:只有长度小于等于当前字符串的串才有可能是它的子串,直接过滤掉所有更长的候选串,大幅减少判断次数
- 重复串批量计算:相同的字符串只做一次子串匹配判断,直接乘以出现次数计入结果,当数据中存在大量重复字符串时性能提升可达数十倍
- 如果字符串量级达到万级以上,还可以引入Aho-Corasick自动机实现O(n*L)的时间复杂度,进一步提升性能。
内容的提问来源于stack exchange,提问作者user17001711
相关产品推荐
相关产品推荐

