行式JSON文件按指定键过滤失败问题排查及解决方法求助
解决行式JSON文件过滤问题
看起来你遇到的问题主要是函数定义的顺序错误,以及代码结构不够严谨导致的。让我一步步帮你分析和解决:
问题分析
- 函数定义位置错误:你在
with代码块里调用了checker(obj),但checker函数是在这之后才定义的。Python是解释型语言,代码从上到下执行,当执行到checker(obj)时,解释器还不知道这个函数存在,这会直接抛出NameError(你可能没注意到这个报错?),导致循环提前终止,所以jsonList始终是空的。 - 依赖全局变量的不良写法:你的
checker函数直接操作全局的jsonList,这种写法不仅不优雅,还容易引发变量作用域的问题。
修正后的代码
我们先调整函数位置,再优化逻辑,让代码更清晰可靠:
import json def should_keep(obj): # 直接返回是否包含目标键,逻辑更简洁 return "name" in obj or "firstname" in obj def filter_json_lines(input_filename, output_filename): kept_objects = [] with open(input_filename, 'r') as f: for line_num, line in enumerate(f, 1): try: obj = json.loads(line.strip()) if should_keep(obj): kept_objects.append(obj) except json.JSONDecodeError as e: # 处理可能的JSON格式错误,避免程序崩溃 print(f"Warning: Line {line_num} has invalid JSON: {e}") # 将结果写入输出文件,每行一个JSON对象 with open(output_filename, 'w') as out_f: for obj in kept_objects: json.dump(obj, out_f) out_f.write('\n') # 调用示例 filter_json_lines("input.json", "output.json")
改进点说明
- 函数提前定义:
should_keep函数在调用前就定义好了,避免了NameError。 - 更简洁的判断逻辑:用
return "name" in obj or "firstname" in obj直接替代原来的check变量,代码更易读。 - 错误处理:添加了
try-except捕获JSON格式错误,避免因为某一行格式问题导致整个程序崩溃,还能提示错误行号方便排查。 - 模块化设计:把过滤逻辑封装成函数,输入输出文件名作为参数,复用性更强。
- 避免全局变量:用局部变量
kept_objects存储结果,更安全。
验证示例数据
用你给出的示例JSON文件测试,输出文件会包含前两行:
{"name": "name1", "date": "2018-11-13", "age": 32} {"firstname": "name2", "date": "2019-05-09", "age": 40}
第三行因为不包含目标键会被过滤掉,完全符合你的需求。
如果你运行原来的代码时没有看到NameError,可能是你实际运行的代码和你贴出来的顺序不一样?可以再检查一下代码的执行顺序哦。
内容的提问来源于stack exchange,提问作者brownleaf
相关产品推荐
相关产品推荐

