如何将包含算术运算的字符串格式列表转换为实际计算后的列表
带算术运算的列表字符串转换方案
json.loads() 仅能解析符合JSON规范的静态字面量,无法识别并计算字符串内的算术表达式,可根据输入的可信程度选择对应实现方式:
快速实现(仅适用于完全可控的可信输入场景)
直接调用Python内置的eval()即可完成自动解析和计算,代码非常简洁:s = "[2-1,2,3]" a = eval(s) # 运行后a的值为 [1, 2, 3]安全提示:
eval()会执行字符串内包含的任意Python代码,严禁用它处理来自用户输入、外部接口等不可信来源的内容,否则会引发严重的代码注入漏洞。安全实现(可处理不可信输入)
基于Python标准库ast做语法白名单校验,只允许列表、数字、基础四则运算出现在解析内容中,拦截所有非法语法后再完成计算,不存在代码注入风险,示例代码如下:import ast import operator # 配置允许的运算符映射,可按需扩展 op_map = { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, ast.USub: operator.neg # 支持负号,比如[3*-1]这类写法 } def calc_node(node): # 处理数字常量 if isinstance(node, ast.Constant) and type(node.value) in (int, float): return node.value # 处理二元运算(比如a-b、a+b这类) if isinstance(node, ast.BinOp) and type(node.op) in op_map: return op_map[type(node.op)](calc_node(node.left), calc_node(node.right)) # 处理一元运算(比如负数) if isinstance(node, ast.UnaryOp) and type(node.op) in op_map: return op_map[type(node.op)](calc_node(node.operand)) # 遇到不支持的语法直接抛错 raise ValueError(f"存在不合法的内容: {ast.dump(node)}") def str_to_calc_list(s: str): ast_tree = ast.parse(s, mode="eval") if not isinstance(ast_tree.body, ast.List): raise ValueError("输入不是合法的列表字符串") return [calc_node(item) for item in ast_tree.body.elts] # 测试 s = "[2-1,2,3*4,10/2,-5+2]" a = str_to_calc_list(s) # 运行后a的值为 [1, 2, 12, 5.0, -3]
内容的提问来源于stack exchange,提问作者M Tomb
相关产品推荐
相关产品推荐

