ast.literal_eval() support for set literals in Python 2.7?

混江龙づ霸主 提交于 2019-12-23 07:37:05

问题


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().


回答1:


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))



回答2:


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.



来源:https://stackoverflow.com/questions/6078262/ast-literal-eval-support-for-set-literals-in-python-2-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!