You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何不用eval实现字符串形式的列表切片/访问操作?

替代eval实现字符串形式的列表切片/访问

需求:将字符串形式的列表访问(或切片)规范,例如"[1]"、"[3:2]"或"[:-4]",应用到Python中的现有列表,但不想使用不安全的eval函数,同时避免自行解析字符串(比如正则无法匹配负数的问题)。

原实现(使用eval):

import sys

mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
myargspec = sys.argv[1] if len(sys.argv) > 1 else ""
print(f"Got command line argument: '{myargspec}'")
mylist_sliced_str = f"mylist{myargspec}"
print(f"... attempting to access: '{mylist_sliced_str}'")
mylist_sliced = eval(mylist_sliced_str)
print(f"... result: {mylist_sliced}")

运行示例:

$ python3 test.py
Got command line argument: ''
... attempting to access: 'mylist'
... result: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

$ python3 test.py "[2]"
Got command line argument: '[2]'
... attempting to access: 'mylist[2]'
... result: 3

$ python3 test.py "[2:4]"
Got command line argument: '[2:4]'
... attempting to access: 'mylist[2:4]'
... result: [3, 4]

$ python3 test.py "[:-4]"
Got command line argument: '[:-4]'
... attempting to access: 'mylist[:-4]'
... result: [1, 2, 3, 4, 5, 6]

安全替代方案:使用ast模块解析索引/切片

可以利用Python内置的ast模块来安全解析字符串形式的索引或切片表达式,它只会处理合法的语法结构,不会执行任意代码,完美规避eval的安全风险,同时无需手动解析字符串。

实现代码:

import sys
import ast
from operator import getitem

mylist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
myargspec = sys.argv[1] if len(sys.argv) > 1 else ""

print(f"Got command line argument: '{myargspec}'")

if not myargspec:
    # 空参数直接返回原列表
    result = mylist
else:
    # 构造合法的表达式用于解析,比如"x[2:4]"
    expr_str = f"x{myargspec}"
    try:
        # 解析表达式为抽象语法树
        tree = ast.parse(expr_str, mode='eval')
        subscript_expr = tree.body
        
        if isinstance(subscript_expr, ast.Subscript):
            # 安全解析切片/索引对象
            slice_or_index = ast.literal_eval(subscript_expr.slice)
            # 执行列表访问/切片
            result = getitem(mylist, slice_or_index)
        else:
            raise ValueError("Invalid subscript expression format")
    except Exception as e:
        print(f"Error parsing spec: {str(e)}")
        sys.exit(1)

print(f"... result: {result}")

方案说明:

  • 利用ast.parse将构造的表达式(如x[-1]、x[::2])解析为抽象语法树,确保只处理合法的下标访问语法
  • 通过ast.Subscript判断表达式类型,再用ast.literal_eval安全提取切片或索引值,支持所有Python合法的切片格式(包括负数、步长)
  • 使用operator.getitem执行列表的下标/切片操作,和直接编写mylist[slice_obj]效果完全一致
  • 空参数逻辑与原实现保持一致,返回完整列表

测试验证:

$ python3 test.py "[-1]"
Got command line argument: '[-1]'
... result: 10

$ python3 test.py "[5:-2]"
Got command line argument: '[5:-2]'
... result: [6, 7, 8]

$ python3 test.py "[::2]"
Got command line argument: '[::2]'
... result: [1, 3, 5, 7, 9]

内容的提问来源于stack exchange,提问作者sdbbs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 21:24:59