【问题标题】:ast.literal_eval() malformed node or string while converting a string with list of array()sast.literal_eval() 在转换带有 array() 列表的字符串时出现格式错误的节点或字符串
【发布时间】:2018-05-29 17:22:20
【问题描述】:

我有一个字符串,它是一个 numpy 数组的列表。 字符串看起来像

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

当我这样做时

ast.literal_eval(k)

我收到一条错误消息,指出节点或字符串格式错误。

这里有什么问题?有没有更好的方法将其转换回列表?

感谢您的帮助!

【问题讨论】:

  • array(…) 是一个电话,而不是字面上的任何东西。您需要创建仅包含常规列表的字符串,或者使用 ast.literal_eval 之前/以外的内容。
  • 你应该首先避免这样做。你为什么得到这些字符串?
  • 这些被序列化为数组而不是列表是否有原因?

标签: python numpy abstract-syntax-tree


【解决方案1】:

来自ast.literal_eval doc

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

这里不能使用文字 eval。首先找到这些字符串的生成位置,并在那里实现适当的序列化 - 例如使用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

    【讨论】:

    • 聪明。只要 OP 数据的形状永不改变,就可以工作——我不会将此作为长期方法,但可以将其视为临时/临时解决方法,直到生成相关字符串的任何内容都得到修复。
    • @CharlesDuffy。我同意,这不是一个适当的解决方案。最好是修复 OP 的输入源。
    【解决方案3】:
    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(),因为后者在生产代码中很危险。
    猜你喜欢
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2017-09-22
    • 2015-12-18
    相关资源
    最近更新 更多