ugly = "[{'ride': 1, 'pickup_time': datetime(2016, 3, 17, 15, 36, 35, 976202)},
{'ride': 2, 'pickup_time': datetime.datetime(2016, 3, 17, 15, 41, 35, 976202)}]"
# The actual variable contains a lot more dictionnaries...`
我想将丑陋的变量转换为真正的Python对象。
我尝试了json.loads()
和ast.literal_eval()
,但仅限于一个字典。
这就是为什么在此之前,我试图将这个字符串拆分成几个字典,但是split()
方法只有一个分隔符,所以看起来我需要一个REGEX才能做到这一点。
最简单的方法是什么?感谢。
答案 0 :(得分:5)
首先,您应该在调用datetime
方法时保持一致。在第一个词典中,您使用datetime
和第二个datetime.datetime
。
无论你尝试使用Python eval字符串,你都不能同时datetime
成为一个函数(第一个字典)和一个模块(第二个)。一旦你解决了这个问题,你将被迫使用邪恶的eval
函数,因为json.loads
而不是ast.litteral_eval
都不接受函数。它们通常用于避免评估调用任何函数......
但如果这是您想要做的(并且您确定ugly
不包含有害代码),则可行:
>>> ugly = "[{'ride': 1, 'pickup_time': datetime.datetime(2016, 3, 17, 15, 36, 35, 976202)},{'ride': 2, 'pickup_time': datetime.datetime(2016, 3, 17, 15, 41, 35, 976202)}]"
>>> import datetime
>>> dlist = eval(ugly)
>>> dlist
[{'ride': 1, 'pickup_time': datetime.datetime(2016, 3, 17, 15, 36, 35, 976202)}, {'ride': 2, 'pickup_time': datetime.datetime(2016, 3, 17, 15, 41, 35, 976202)}]
答案 1 :(得分:4)
您可以使用eval
a = eval(ugly)
此时a是一个词典列表,我相信你从那里得到它。
答案 2 :(得分:0)
您可以使用eval
获取字典数组(修复datetime
问题后),然后使用setattr
将字典转换为实际的类对象:
from datetime import datetime
ugly = "[{'ride': 1, 'pickup_time': datetime(2016, 3, 17, 15, 36, 35, 976202)}, {'ride': 2, 'pickup_time': datetime(2016, 3, 17, 15, 41, 35, 976202)}]"
array = eval(ugly)
class Ride(object):
pass
rides = []
for record in array:
ride = Ride()
for k, v in record.iteritems():
setattr(ride, k, v)
rides.append(ride)
for ride in rides:
print "ride: {0}: pickup_time: {1}".format(ride.ride, ride.pickup_time)
答案 3 :(得分:0)
取决于您要导入datetime
的方式:
import datetime
ugly = "[{'ride': 1, 'pickup_time': datetime(2016, 3, 17, 15, 36, 35, 976202)},{'ride': 2, 'pickup_time': datetime.datetime(2016, 3, 17, 15, 41, 35, 976202)}]"
ugly = ugly.replace(" datetime(", " datetime.datetime(")
ugly = eval(ugly)
或
from datetime import datetime
ugly = "[{'ride': 1, 'pickup_time': datetime(2016, 3, 17, 15, 36, 35, 976202)},{'ride': 2, 'pickup_time': datetime.datetime(2016, 3, 17, 15, 41, 35, 976202)}]"
ugly = ugly.replace("datetime.", "")
ugly = eval(ugly)
无需事先清除ugly
答案 4 :(得分:0)
你可以通过提取datetimes
及其键只调用这些配对上的eval来使用正则表达式来实现它:
from datetime import datetime
from ast import literal_eval
import re
def parse(ug):
ug = ug.replace("datetime.", "")
pairs = ("{{{}}}".format(p) for p in re.findall("('\w+':\s+datetime\(.*\))", ug))
_parsed = literal_eval(re.sub("datetime\(.*\)","''", ug))
for d in _parsed:
d.update(eval(next(pairs)))
return _parsed
列表将被订购,因此正确的配对将被放回正确的序列中:
In [4]: parse(ugly)
Out[4]:
[{'pickup_time': datetime.datetime(2016, 3, 17, 15, 36, 35, 976202),
'ride': 1},
{'pickup_time': datetime.datetime(2016, 3, 17, 15, 41, 35, 976202),
'ride': 2}]