Python转换JSON为列表的列表时列表引用异常修复方案
问题原因
你碰到的是Python列表的引用传递特性导致的bug:
你在循环外只初始化了一次entity列表,后续每次调用entity.clear()、追加元素、将entity追加到all_entities时,存入all_entities的都是同一个内存地址的列表引用,不是独立的新列表。只要你修改entity的内容,之前所有追加到all_entities里、指向同一个内存地址的条目都会同步更新,最终所有条目都会变成entity最后一次被修改的内容。
修复方法
- 删掉全局定义的
entity变量,不要复用同一个临时列表存不同条目。每次处理单个实体位置时,在循环内部新建独立的空列表,处理完成后直接追加到结果列表,从根源避免引用互相干扰。 - 你手动替换括号、引号解析位置字符串的写法很容易出边界问题,直接用Python标准库
ast.literal_eval可以直接把字符串格式的列表转为真实的Python列表,不需要手动处理特殊字符,稳定性更高。
修复后代码
import ast import spacy import json nlp = spacy.load("en_core_web_sm") ner = nlp.get_pipe('ner') all_entities = [] df_prep = [] data = json.loads(j) for text in data: doc = nlp(text['pn_history']) xx = [token.text for token in doc] yy = [token.pos_ for token in doc] for x in text['entities']: loc_str_raw, feature_text = x.values() # 直接将字符串格式的位置列表转为Python列表 loc_list = ast.literal_eval(loc_str_raw) for loc_pair in loc_list: # 每次处理单个位置对,新建独立列表 start, end = map(int, loc_pair.split()) all_entities.append([start, end, feature_text]) # 测试用的break记得正式运行时删除 break
运行效果
针对你给出的样例数据,代码会输出符合预期的结果:
[[334, 366, 'No-relief-with-asthma-inhaler'], [25, 30, 'Sharp-OR-stabbing-OR-7-to-8-out-of-10-on-pain-scale'], [149, 153, 'Sharp-OR-stabbing-OR-7-to-8-out-of-10-on-pain-scale']]
不会再出现所有条目同步变化的问题。
内容的提问来源于stack exchange,提问作者tanmay
相关产品推荐
相关产品推荐

