我有傾倒多個defaultdict用一個簡單的打印命令,就像這樣:解析defaultdict串
defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})
有一些標準的解析器,我可以用它來獲取它們?我知道我應該使用pickle,但生成這些defaultdict的代碼非常慢,我想避免重新運行它。
我有傾倒多個defaultdict用一個簡單的打印命令,就像這樣:解析defaultdict串
defaultdict(<type 'list'>, {'actual': [20000.0, 19484.0, 19420.0], 'gold': [20000.0, 19484.0, 19464.0]})
有一些標準的解析器,我可以用它來獲取它們?我知道我應該使用pickle,但生成這些defaultdict的代碼非常慢,我想避免重新運行它。
完全難看,但工作原理:
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。
如果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)
+1使用'eval';) – georg
你可以讓自己的子類:
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': []})
請注意,使用這種方式,即使某些對同一對象的引用,也會爲結構中的每個對象引用創建單獨的副本。
推測,你也可以使用內置的JSON解析器。 –
使用'ast'的+1。 –