解析 defaultdict 字符串

3

我用一个简单的打印命令来转储多个defaultdict,如下所示:

defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})

有没有一些标准的解析器可以用来检索它们?我知道我应该使用pickle,但生成这些defaultdict的代码非常缓慢,我想避免重新运行它。

3个回答

6
如果你的defaultdict类型总是<type 'list'>,那么可以使用以下代码:
from collections import defaultdict

s = """
defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})
"""
data = eval(s.replace("<type 'list'>", 'list'))

人们会告诉你eval()是不安全和邪恶的,但如果有人试图将有害代码注入到你倾泻出来的数据中,他们可能同样容易地编辑你的源代码。如果文本文件比你的源代码更容易访问,那么你可能不想使用这种方法。
如果您的defaultdicts有多个类型,但都是内置类型(或者易于在repr和类型名称之间转换),那么您仍然可以使用多个替换的方法,例如:
for rep, typ in ((repr(list), 'list'), (repr(dict), 'dict')):
    s = s.replace(rep, typ)
data = eval(s)

2

非常丑陋,但是可行:

s = """
defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})
"""

import re, ast

s = re.sub('^[^{]+', '', s)
s = re.sub('[^}]+$', '', s)

print ast.literal_eval(s)

请注意,这将创建一个普通的dict,而不是一个defaultdict。

据推测,您也可以使用内置的JSON解析器。 - Joel Cornett

0

你可以创建自己的子类:

from collections import defaultdict

class mydefdict(defaultdict):
     def __repr__(self):
         return "mydefdict(%s, %s)" % (repr(self.default_factory()) + ".__class__", repr(dict(self)))

然后像其他类型一样使用eval

>>> d = mydefdict(list)
>>> d['foo'] = [1,2,3]
>>> d['bar']
[]
>>> print d
mydefdict([].__class__, {'foo': [1, 2, 3], 'bar': []})
>>> reprstring = repr(d)
>>> d2 = eval(reprstring)
>>> d2
mydefdict([].__class__, {'foo': [1, 2, 3], 'bar': []})

请注意,使用这种方式,将为结构中的每个对象引用创建一个单独的副本,即使其中一些是对同一对象的引用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接