ast.literal_eval() 支持 Python 2.7 中的集合文字吗?

发布于 2024-11-08 23:09:06 字数 927 浏览 6 评论 0原文

What's New in Python 2.7 文档中,它说对集合文字的支持是从 Python 3.1 向后移植的。然而,这种支持似乎并未扩展到 ast 模块的 literal_eval() 函数,如下所示。

这是故意的、疏忽的还是其他原因——从字符串表示创建文字集的最干净的解决方法是什么? (我假设以下内容在 Python 3.1+ 中有效,对吧?)

import ast
a_set = {1,2,3,4,5}
print(a_set) 
print(ast.literal_eval('{1,2,3,4,5}'))

输出显示错误消息:

set([1, 2, 3, 4, 5])
Traceback (most recent call last):
  File "...\setliterals.py", line 4, in <module>
    print ast.literal_eval('{1,2,3,4,5}')
  File "...\Python\lib\ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "...\Python\lib\ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

PS 我能想到的唯一解决方法是使用 eval()

In the What’s New in Python 2.7 document it says that support for set literals was back-ported from Python 3.1. However it appears that this support was not extended to the ast module's literal_eval() function, as illustrated below.

Was this intentional, an oversight, or something else — and what are the cleanest workarounds for creating a literal set from a string representation? (I assume the following works in Python 3.1+, right?)

import ast
a_set = {1,2,3,4,5}
print(a_set) 
print(ast.literal_eval('{1,2,3,4,5}'))

Output showing error message:

set([1, 2, 3, 4, 5])
Traceback (most recent call last):
  File "...\setliterals.py", line 4, in <module>
    print ast.literal_eval('{1,2,3,4,5}')
  File "...\Python\lib\ast.py", line 80, in literal_eval
    return _convert(node_or_string)
  File "...\Python\lib\ast.py", line 79, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

P.S. The only workaround I can think of is to use eval().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

影子的影子 2024-11-15 23:09:06

我一直在使用它来转换 pandas DataFrame 中的列(df[col] = df[col].apply(to_set)。对于发现这个问题的任何人来说可能有用。它可能不像速度很快,但它避免使用eval

def to_set(set_str):
    """
    Required to get around the lack of support for sets in ast.literal_eval. 
    It works by converting the string to a list and then to a set.

    Parameters
    ----------
    set_str : str
        A string representation of a set.

    Returns
    -------
    set

    Raises
    ------
    ValueError
        "malformed string" if the string does not start with '{' and and end 
        with '}'.

    """
    set_str = set_str.strip()
    if not (set_str.startswith('{') and set_str.endswith('}')):
        raise ValueError("malformed string")

    olds, news = ['{', '}'] , ['[',']']
    for old, new in izip(olds, news):        
        set_str = set_str.replace(old, new)

    return set(literal_eval(set_str))

I've been using this for converting columns in a pandas DataFrame (df[col] = df[col].apply(to_set). Might be useful for anyone finding this question. It may not be as fast but it avoids using eval.

def to_set(set_str):
    """
    Required to get around the lack of support for sets in ast.literal_eval. 
    It works by converting the string to a list and then to a set.

    Parameters
    ----------
    set_str : str
        A string representation of a set.

    Returns
    -------
    set

    Raises
    ------
    ValueError
        "malformed string" if the string does not start with '{' and and end 
        with '}'.

    """
    set_str = set_str.strip()
    if not (set_str.startswith('{') and set_str.endswith('}')):
        raise ValueError("malformed string")

    olds, news = ['{', '}'] , ['[',']']
    for old, new in izip(olds, news):        
        set_str = set_str.replace(old, new)

    return set(literal_eval(set_str))
缱倦旧时光 2024-11-15 23:09:06

从错误报告中: http://bugs.python.org/issue10091

Raymond Hettinger 说:

ast.literal_eval 的文档:

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

我相信我们可以从这篇文档中得出结论,这个问题不一定是一个错误,因为集合文字是从 Python 3.2 向后移植到 3.1 和 2.7 的。这是 ast.literal 的 Python 2.7 用户应该注意的事情。

From the bug report: http://bugs.python.org/issue10091

Raymond Hettinger says:

ast.literal_eval's docs:

'The string or node provided may only consist of the following Python
literal structures: strings, numbers, tuples, lists, dicts, booleans,
and None.'

I believe we can conclude from this document that the matter is not necessarily a bug, since the set literal was backported from Python 3.2 to 3.1 and 2.7. It is something that a Python 2.7 user of ast.literal should be aware of.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文