【发布时间】:2019-07-18 04:21:34
【问题描述】:
我想编写一个函数,该函数根据子字符串的最小和最大长度有效地返回字符串的所有可能子字符串的列表。 (字符串只包含大写字母。)
例如,对于字符串'THISISASTRING',对于min_length=3 和max_length=4,它应该返回:
['THI', 'THIS', 'HIS', 'HISI', 'ISI', 'ISIS', 'SIS', 'SISA', 'ISA',
'ISAS', 'SAS', 'SAST', 'AST', 'ASTR', 'STR', 'STRI', 'TRI', 'TRIN',
'RIN', 'RING', 'ING']
我正在寻找一种比我目前的解决方案更快的解决方案:
import cProfile
random_english_text = \
'AHOUSEISABUILDINGTHATISMADEFORPEOPLETOLIVEINITISAPERMANENTBUILDINGTHATISMEANTTOSTAYSTANDINGITISNOTEASILYPACKEDU' \
'PANDCARRIEDAWAYLIKEATENTORMOVEDLIKEACARAVANIFPEOPLELIVEINTHESAMEHOUSEFORMORETHANASHORTSTAYTHENTHEYCALLITTHEIRHO' \
'MEBEINGWITHOUTAHOMEISCALLEDHOMELESSNESSHOUSESCOMEINMANYDIFFERENTSHAPESANDSIZESTHEYMAYBEASSMALLASJUSTONEROOMORTH' \
'EYMAYHAVEHUNDREDSOFROOMSTHEYALSOAREMADEMANYDIFFERENTSHAPESANDMAYHAVEJUSTONELEVELORSEVERALDIFFERENTLEVELSAHOUSEI' \
'SSOMETIMESJOINEDTOOTHERHOUSESATTHESIDESTOMAKEATERRACEORROWHOUSEACONNECTEDROWOFHOUSES'
def assemble_substrings(textstring, length_min, length_max):
str_len = len(textstring)
subStringList = []
idx = 0
while idx <= str_len - length_min:
max_depth = min(length_max, str_len - idx)
for i in list(range(length_min, max_depth + 1)):
subString = textstring[idx:idx + i]
subStringList.append(subString)
idx += 1
return subStringList
pr = cProfile.Profile()
pr.enable()
for i in range(0, 1000):
list_of_substrings = assemble_substrings(textstring=random_english_text, length_min=4, length_max=10)
pr.disable()
pr.print_stats(sort='cumtime')
这产生了我:
ncalls tottime percall cumtime percall filename:lineno(function)
1000 1.332 0.001 1.672 0.002 <input>:11(assemble_substrings)
3654000 0.227 0.000 0.227 0.000 {method 'append' of 'list' objects}
525000 0.112 0.000 0.112 0.000 {built-in method builtins.min}
1000 0.000 0.000 0.000 0.000 {built-in method builtins.len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
现在,从分析器的输出来看,我对如何加速此功能没有太多了解。
使此功能尽可能快的最佳方法是什么? 我应该使用与列表不同的数据结构吗? 使用赛通?还是将这段代码写在外部 C/C++ 共享对象中?
非常感谢输入,通常还包括如何有效地处理类似于上述 Python 中的字符串和操作。
【问题讨论】:
-
你想用这个做什么?可能有比包含所有选项的列表更好的数据结构。
-
另外我认为你有一个边缘情况的错误,当循环位于字符串的最后一个 length_min 个字符时,它仍然为每个允许的长度添加字符串。我认为字符串的结尾需要被视为特殊情况。
-
对于结果列表(或其他数据结构)中的所有项目,我希望能够: 1. 检查每个项目,如果它们包含在另一个列表(或其他数据结构)中) 2. 遍历所有元素并将它们用作访问字典的键
-
你的问题让我想起了其他问题的一部分,虽然我不记得具体是哪一个。也许k-nucleotide?
-
你为什么使用
list(range(...))?似乎没有必要打电话给list()。