在What’s New in Python 2.7文档中,它表示支持set literals是从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
P.S。我能想到的唯一解决方法是使用eval()
。
答案 0 :(得分:1)
我一直在使用它来转换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))
答案 1 :(得分:0)
来自错误报告:http://bugs.python.org/issue10091
Raymond Hettinger说:
ast.literal_eval的文档:
'提供的字符串或节点可能只包含以下Python 文字结构:字符串,数字,元组,列表,dicts,布尔值, 没有。'
我相信我们可以从这份文件中得出结论,这个问题不一定是一个bug,因为set literal从Python 3.2反向移植到3.1和2.7。 是 ast.literal
的Python 2.7用户应该知道的东西。