繁体   English   中英

如何将包含dict列表的字符串转换为Python对象?

[英]How to convert a string containing a list of dict into Python object?

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()但它只适用于一个dict。

这就是为什么在此之前,我试图将这个字符串拆分成几个字典,但split()方法只有一个分隔符,所以看起来我需要一个REGEX才能做到这一点。

最简单的方法是什么? 谢谢。

首先,你应该在调用datetime方法时保持一致。 在第一个dict中,您使用datetime和第二个datetime.datetime

无论你尝试使用Python eval字符串,你都不能同时将datetime作为一个函数(第一个字典)和一个模块(第二个)。 一旦你解决这个问题,你将被迫使用邪恶eval函数,因为无论json.loadsast.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)}]

你可以使用eval

a = eval(ugly)

在这一点上,a是一个词典列表,我相信你从那里得到它。

您可以使用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)

根据您要导入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

你可以通过提取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}]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM