如何将分词后的句子列表转换为无多余空格的规范字符串?
优化分词列表转字符串的实现方案
你的分块处理方法存在明显的边界问题(比如列表长度为奇数时,最后一个块只有单个元素,访问words[1]会抛出索引错误),而且逻辑不够灵活,无法处理多个连续标点或复杂的标点组合场景。下面提供两种更高效、鲁棒的实现方式:
方法一:单次遍历拼接(推荐)
通过一次遍历分词列表,根据当前token和前一个token的类型,决定是否添加空格,逻辑清晰且效率最高:
def join_tokens(tokens): if not tokens: return "" # 定义需要紧贴前后的标点集合,可按需扩展 tight_punctuation = {'-', "'", ':', '.'} result = [tokens[0]] for token in tokens[1:]: # 如果当前token是紧标点,或者前一个元素是紧标点,直接拼接 if token in tight_punctuation or result[-1] in tight_punctuation: result[-1] += token else: result.append(token) return ' '.join(result)
测试你的示例输入:
text = ['Selegiline', '-', 'induced', 'postural', 'hypotension', 'in', 'Parkinson', "'", 's', 'disease', ':', 'a', 'longitudinal', 'study', 'on', 'the', 'effects', 'of', 'drug', 'withdrawal', '.'] print(join_tokens(text)) # 输出:Selegiline-induced postural hypotension in Parkinson's disease: a longitudinal study on the effects of drug withdrawal.
优势:
- 时间复杂度O(n),仅需一次遍历
- 无边界问题,兼容任意长度的分词列表
- 可扩展性强,新增紧标点只需添加到集合中
- 处理逻辑直观,易于调试和维护
方法二:正则表达式替换
如果追求代码简洁,可先将所有token用空格连接,再通过正则去掉紧标点前后的多余空格:
import re def join_tokens_regex(tokens): if not tokens: return "" tight_punctuation = {'-', "'", ':', '.'} # 先拼接所有token joined = ' '.join(tokens) # 遍历替换每个紧标点前后的空格 for punct in tight_punctuation: escaped_punct = re.escape(punct) # 替换"空格+标点"和"标点+空格"为纯标点 joined = re.sub(rf'\s+{escaped_punct}', escaped_punct, joined) joined = re.sub(rf'{escaped_punct}\s+', escaped_punct, joined) return joined
优势:
- 代码简洁,无需复杂的遍历判断
- 自动处理连续空格的情况
注意:
- 需要导入
re模块,且要注意转义正则特殊字符(比如-需要转义) - 对于超长文本,效率略低于单次遍历方法
内容的提问来源于stack exchange,提问作者Aaditya Ura
相关产品推荐
相关产品推荐

