ast.literal_eval()在将一个包含array()列表的字符串转换时出现了格式错误的节点或字符串。

3

我有一个字符串,其中包含一个numpy数组的列表。 该字符串的格式如下:

k = '[array([  0, 269, 175, 377]), array([  0,  56, 149, 163])]'

当我执行

ast.literal_eval(k)

我遇到了一个错误,显示节点或字符串格式不正确。

问题出在哪里?有没有更好的方法将其转换回列表?

谢谢帮助!


1
array(…) 是一个调用,而不是字面上的任何东西。你需要仅使用常规列表创建字符串或在 ast.literal_eval 之前/之外使用其他内容。 - Ry-
2
你应该尽量避免一开始就这么做。你为什么会获取这些字符串? - juanpa.arrivillaga
这些为什么被序列化为数组,而不是列表? - Charles Duffy
3个回答

4
ast.literal_eval文档中:

提供的字符串或节点只能由以下Python文字结构组成:字符串、字节、数字、元组、列表、字典、集合、布尔和 None。

在此不可能使用文字评估。找到这些字符串最初生成的位置,并在那里实现适当的序列化-例如使用numpy.save

2

我不确定这是否是一个好的方法。

from numpy import array
import ast
import re
k = '[array([  0, 269, 175, 377]), array([  0,  56, 149, 163])]'
val = re.findall(r"\((.*?)\)", k)
val = list(map(ast.literal_eval, val))
val = list(map(array, val))
print(val)

输出:

[array([  0, 269, 175, 377]), array([  0,  56, 149, 163])]
  • 使用正则表达式提取()之间的内容
  • 应用ast.literal_eval
  • 应用np.array

1
聪明。只要 OP 的数据形状不改变,它就能正常工作——我不会选择这种长期方法,但可以将其视为临时/过渡性解决方案,直到生成相关字符串的任何内容得到修复。 - Charles Duffy
@CharlesDuffy。我同意,这不是一个合适的解决方案。最好的方法是在OP输入源处进行修复。 - Rakesh

0
import numpy as np

array = np.array
k = '[array([  0, 269, 175, 377]), array([  0,  56, 149, 163])]'
k = eval(k)
print(f"k = {k}, type of k = {type(k)}")
print(type(k[0]))

输出:

k = [array([  0, 269, 175, 377]), array([ 0, 56])], type of k = <class 'list'>

<class 'numpy.ndarray'>

literal_eval() 的整个目的是避免在生产代码中使用 eval(),因为后者是危险的。 - SigmaX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接