【发布时间】:2012-03-01 15:20:30
【问题描述】:
我需要将一个字符串拆分成单词,还要获取单词的开始和结束偏移量。因此,例如,如果输入字符串是:
input_string = "ONE ONE ONE \t TWO TWO ONE TWO TWO THREE"
我想得到:
[('ONE', 0, 2), ('ONE', 5, 7), ('ONE', 9, 11), ('TWO', 17, 19), ('TWO', 21, 23),
('ONE', 25, 27), ('TWO', 29, 31), ('TWO', 33, 35), ('THREE', 37, 41)]
我有一些使用 input_string.split 和调用 .index 的工作代码,但速度很慢。我尝试通过手动迭代字符串来对其进行编码,但这仍然比较慢。有人对此有快速算法吗?
这是我的两个版本:
def using_split(line):
words = line.split()
offsets = []
running_offset = 0
for word in words:
word_offset = line.index(word, running_offset)
word_len = len(word)
running_offset = word_offset + word_len
offsets.append((word, word_offset, running_offset - 1))
return offsets
def manual_iteration(line):
start = 0
offsets = []
word = ''
for off, char in enumerate(line + ' '):
if char in ' \t\r\n':
if off > start:
offsets.append((word, start, off - 1))
start = off + 1
word = ''
else:
word += char
return offsets
通过使用 timeit,“using_split”是最快的,其次是“manual_iteration”,到目前为止最慢的是使用 re.finditer,如下所示。
【问题讨论】:
-
如果你有任何重复字符的长单词,line.index(word[0], running_offset) 比 line.index(word, running_offset) 快(除非你有很多空白) .你可以去 (i for i,c in enumerate(word) of c==word[0]).next()