簡體   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