Spacy(Python3.10)token.lefts方法随机返回空列表问题咨询
Spacy token.lefts/rights随机返回空列表的成因分析
- 变量名覆盖问题:这是导致"随机"异常的核心原因。
nsubj_finder函数中,你先用token = doc[token.i]拿到了待处理的目标token,紧接着for token in token.lefts的迭代变量也用了token这个名字,直接覆盖了原有的目标token对象。每次迭代后原token都会被替换为左子节点,一旦某次循环没有匹配到nsubj,后续拿到的token就不是你预期的对象,自然会出现有时候有左子节点有时候没有的假象。 - 导入语句错误:你写的
from spacy.tokens import token是错误写法,spaCy的Token类首字母大写,小写导入的是模块而非Token类,会导致token对象的属性判断出现不可预期的异常行为。 - 统计模型的非确定性:spaCy的预训练模型是统计模型,如果你没有固定随机种子,不同运行环境、不同模型版本下的依赖解析结果会有细微差异,部分场景下目标节点确实没有左/右子节点,此时返回空列表是正常的模型输出。
- 函数逻辑漏洞:
nsubj_finder只有匹配到nsubj时才会显式返回phrase,未匹配到的场景没有return语句,会默认返回None;- 你直接迭代
token.lefts没有做边界判断,当传入的token本身就是依赖树根节点、或者本身没有左子节点时,lefts自然为空列表。
- 上游函数的逻辑错误:
number_exctractor中判断if token not in list(token.head.lefts)时,如果当前token已经是根节点,token.head会指向自身,此时token.head.lefts是根节点的左子节点列表,永远不会包含根节点自己,循环会直接终止,此时返回的token可能本身就没有左子节点,传给nsubj_finder后自然返回空。
核心修复示例
def nsubj_finder(doc, phrase, input_token): # 修改变量名避免覆盖 current_token = doc[input_token.i] for left_child in current_token.lefts: if left_child.dep_ == "nsubj": left_part = ' '.join([t.text for t in left_child.lefts]) phrase = f"{left_part} {left_child.text} {phrase}".strip() return phrase # 未找到nsubj时返回原短语避免返回None return phrase
内容的提问来源于stack exchange,提问作者Scolpe
相关产品推荐
相关产品推荐

