您可以檢查您是否已經使用literal_eval並重新分配後的字典:
from ast import literal_eval
def reassign(d):
for k, v in d.items():
try:
evald = literal_eval(v)
if isinstance(evald, dict):
d[k] = evald
except ValueError:
pass
只是通過在字典:
In [2]: my_dict = {'a': 42, 'b': "my_string", 'c': "{'d': 33, 'e': 'another stri
...: ng'}"}
In [3]: reassign(my_dict)
In [4]: my_dict
Out[4]: {'a': 42, 'b': 'my_string', 'c': {'d': 33, 'e': 'another string'}}
In [5]: my_dict = {'a': '42', 'b': "my_string", '5': "{'d': 33, 'e': 'another st
...: ring', 'other_dict':{'foo':'bar'}}"}
In [6]: reassign(my_dict)
In [7]: my_dict
Out[7]:
{'5': {'d': 33, 'e': 'another string', 'other_dict': {'foo': 'bar'}},
'a': '42',
'b': 'my_string'}
你也應該知道,如果您在字典中有某些其他對象,例如datetime對象等。然後,literal_eval將失敗,因此它是真實的取決於你的字典可以包含的內容是否會起作用。
如果您需要遞歸方法,您只需要在新字典上調用重新分配。
def reassign(d):
for k, v in d.items():
try:
evald = literal_eval(v)
if isinstance(evald, dict):
d[k] = evald
reassign(evald)
except ValueError:
pass
而且又剛剛通過字典:
In [10]: my_dict = {'a': 42, 'b': "my_string", 'c': "{'d': 33, 'e': \"{'f' : 64}
...: \"}"}
In [11]: reassign(my_dict)
In [12]: my_dict
Out[12]: {'a': 42, 'b': 'my_string', 'c': {'d': 33, 'e': {'f': 64}}}
如果你想有一個新的字典:
from ast import literal_eval
from copy import deepcopy
def reassign(d):
for k, v in d.items():
try:
evald = literal_eval(v)
if isinstance(evald, dict):
yield k, dict(reassign(evald))
except ValueError:
yield k, deepcopy(v)
,這將給你一個新的字典:
In [17]: my_dict = {'a': [1, 2, [3]], 'b': "my_string", 'c': "{'d': 33, 'e': \"{
...: 'f' : 64}\"}"}
In [18]: new = dict(reassign(my_dict))
In [19]: my_dict["a"][-1].append(4)
In [20]: new
Out[20]: {'a': [1, 2, [3]], 'b': 'my_string', 'c': {'d': 33, 'e': {'f': 64}}}
In [21]: my_dict
Out[21]:
{'a': [1, 2, [3, 4]],
'b': 'my_string',
'c': '{\'d\': 33, \'e\': "{\'f\' : 64}"}'}
您需要確保深層複製對象,或者當您有像上面列表的列表一樣的嵌套對象時,您將不會得到字典的真實獨立副本。
我認爲戰略是EVAL,然後運行'isinstance'或類似的檢查,如果它是一個字典 –
東西你能做出一個例子嗎?因爲如果我遞歸地評估字典中的值,我會得到一個錯誤。 – Hakaishin
在try/except中使用literal_eval,檢查它是否是嘗試中的字典,並將該鍵重新分配給新值 –