ast.literal_eval () поддержка для набора литералов в Python 2.7? - PullRequest
12 голосов
/ 21 мая 2011

В документе Что нового в Python 2.7 говорится, что поддержка заданных литералов была перенесена из Python 3.1. Однако похоже, что эта поддержка не была расширена до функции ast модуля *1003*, как показано ниже.

Было ли это преднамеренным, упущением или чем-то еще - и каковы самые чистые обходные пути для создания набора литералов из строкового представления? (Я предполагаю, что следующие работы в 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

P.S. Единственный обходной путь, который я могу придумать, - это использовать eval().

Ответы [ 2 ]

1 голос
/ 03 декабря 2015

Я использовал это для преобразования столбцов в панде 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))
0 голосов
/ 06 июня 2014

Из отчета об ошибке: http://bugs.python.org/issue10091

Раймонд Хеттингер говорит:

Документы ast.literal_eval:

'Предоставленная строка или узел может состоять только из следующего Python буквенные структуры: строки, числа, кортежи, списки, диктанты, логические значения, и нет. '

Я полагаю, что из этого документа мы можем сделать вывод, что проблема не обязательно является ошибкой, поскольку заданный литерал был перенесен с Python 3.2 на 3.1 и 2.7. Это - это то, о чем должен знать пользователь Python 2.7 ast.literal.

...