簡體   English   中英

如何在分層數據結構中以python中的功能方式將字符串轉換為dict?

[英]How to convert a string into dict in hierarchical data scructure the functional way in python?

假設我有以下 python 數據結構,其中runtimeArgs包含一個 json 字符串,而不是 python dict。

[
   {
      "runid":"57d45a60-2b34-11ec-8b92-16c898d5a004",
      "properties":{
         "runtimeArgs":"{\"date\":\"2021_10_11\",\"logical.start.time\":\"1634026435347\"}",
         "phase-1":"7bc31901-2b34-11ec-9194-42010a0c0054"
      }
   },
   {
      "runid":"24f7887e-2b28-11ec-b60c-16c898d5a004",
      "properties":{
         "runtimeArgs":"{\"date\":\"2021_10_11\",\"logical.start.time\":\"1634021196053\"}",
         "phase-1":"4712bfa1-2b28-11ec-8968-42010a0c005a"
      }
   }
]

# this is working
my_list[0]["properties"]['runtimeArgs']

# this not working
my_list[0]["properties"]['runtimeArgs']['date']

使用for循環和json.loads()我可以將其轉換為 python dict,但我想以更實用的方式執行此操作,例如: maplist comprehension等。

怎么可能做到這一點?

預期結果:

[
   {
      "runid":"57d45a60-2b34-11ec-8b92-16c898d5a004",
      "properties":{
         "runtimeArgs":{"date":"2021_10_11","logical.start.time":"1634026435347"},
         "phase-1":"7bc31901-2b34-11ec-9194-42010a0c0054"
      }
   },
   {
      "runid":"24f7887e-2b28-11ec-b60c-16c898d5a004",
      "properties":{
         "runtimeArgs":{"date":"2021_10_11","logical.start.time":"1634021196053"},
         "phase-1":"4712bfa1-2b28-11ec-8968-42010a0c005a"
      }
   }
]

# this should work
my_list[0]["properties"]['runtimeArgs']['date']

更新:

我可以自己解決的一種方法(我不喜歡)是這樣的:

[{**x, "properties": { "runtimeArgs" : json.loads(x["properties"]["runtimeArgs"]) }} for x in my_list if x]

有沒有更好的方法來做到這一點?

退后一點,你為什么要這樣做? 以下是我能想到的幾個原因,以及適當的解決方案:

因為我想自己實現 JSON 解析器,功能上,為了練習

在這種情況下,您主要靠自己,但一個可迭代的標記器可能是要走的路。

因為像從這個 json 格式的字符串中獲取元素 x 這樣簡單的事情應該很容易,而且我只需要做一次

在這種情況下,使用 json.loads,但將您的訪問權限封裝在一個函數中:

def get_json(json, key):
    return json.loads(json)[key]

get_json(l[0]["properties"], "date") # this is a function.  I reckon that's functional.  Here with a comprehension:

{l["runid"]: get_json(x["properties"], "date") for x in l}

因為我想從結構中取出數據,邊走邊反序列化

使用一個函數:

def get_parse(thing, key):
    try:
        return thing[key]
    except ValueError:
        return json.loads(thing)[key]

get_parse(get_parse(l[0], "properties"), "date")

如果你願意,這個函數可以遞歸,返回最里面的元素。

我不知道這些原因是否正確涵蓋了您的用例,但它們可能會有所幫助。 基本方法(對函數式編程來說很重要!)是將困難的邏輯放在一個函數中,然后如果你願意的話,可以在你的理解中使用它。

JIT 解析解決方案

純粹是為了好玩,因為這對我嘮叨,這里是一個類似 JS 的 JIT 解析類:

from json import loads


class JITParser:
    def __init__(self, thing):
        if not hasattr(thing, "__getitem__"):
            self._thing = loads(thing)
        else:
            self._thing = thing

    def get(self, key):
        val = self._thing[key]
        if isinstance(val, dict):
            return JITParser(val)
        else:
            try:
                return JITParser(loads(val))
            except ValueError:
                return val

    def __repr__(self):
        return f"JITParser with {repr(self._thing)}"


L = [
    {
        "runid": "57d45a60-2b34-11ec-8b92-16c898d5a004",
        "properties": {
            "runtimeArgs": '{"date":"2021_10_11","logical.start.time":"1634026435347"}',
            "phase-1": "7bc31901-2b34-11ec-9194-42010a0c0054",
        },
    },
    {
        "runid": "24f7887e-2b28-11ec-b60c-16c898d5a004",
        "properties": {
            "runtimeArgs": '{"date":"2021_10_11","logical.start.time":"1634021196053"}',
            "phase-1": "4712bfa1-2b28-11ec-8968-42010a0c005a",
        },
    },
]

j = JITParser(L[0])
j.get("runid")
j.get("properties")
j.get("properties").get("runtimeArgs")
j.get("properties").get("runtimeArgs").get("date")

此類將解析字典或字典的 json 表示,並返回包裝它們的 JITParser 對象,直到遇到無法解析為 JSON 的內容,在這種情況下,它將返回對象本身。

有很多可能的改進:你可以想到:

  • 子類 dict 並具有[]訪問權限
  • 實現列表的遞歸解析
  • 處理其他類型,例如帶有.dotaccess對象。
  • 等等

但模擬起來很有趣,它可能會激勵你,所以我會把它留在這里。 嘗試一下:這很有趣。

對於這組特定的數據,您可以這樣做:

L = [
   {
      "runid":"57d45a60-2b34-11ec-8b92-16c898d5a004",
      "properties":{
         "runtimeArgs":"{\"date\":\"2021_10_11\",\"logical.start.time\":\"1634026435347\"}",
         "phase-1":"7bc31901-2b34-11ec-9194-42010a0c0054"
      }
   },
   {
      "runid":"24f7887e-2b28-11ec-b60c-16c898d5a004",
      "properties":{
         "runtimeArgs":"{\"date\":\"2021_10_11\",\"logical.start.time\":\"1634021196053\"}",
         "phase-1":"4712bfa1-2b28-11ec-8968-42010a0c005a"
      }
   }
]

for d in L:
    print(eval(d['properties']['runtimeArgs'])['date'])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM