【问题标题】:Formatting string representation of structure to python dictionary将结构的字符串表示格式化为python字典
【发布时间】:2021-06-17 06:57:04
【问题描述】:

考虑到字符串不是通用格式,而是 UDF 函数的输出,我需要一些帮助来处理字符串到字典

PySpark UDF 的返回类似于以下字符串:

"{list=[{a=1}, {a=2}, {a=3}]}"

我需要将其转换为具有以下结构的python字典:

{
  "list": [
    {"a": 1}
    {"a": 2}
    {"a": 3}
  ]
}

所以我可以访问它的值,比如

dict["list"][1]["a"]

我已经尝试过使用:

  • JSON.loads
  • ast_eval()

有人可以帮帮我吗?

作为如何生成这个未解析字符串的示例:

@udf()
def execute_method():
  return {"list": [{"a":1},{"b":1}{"c":1}]}

df_result = df_source.withColumn("result", execute_method())

【问题讨论】:

  • 我不认为{list=[{a=1}, {a=2}, {a=3}]} 是 JSON。 {list: [{a: 1}, {a: 2}, {a: 3}]} 将是
  • 试试<original string name>.replace("=", ": ")。它将用冒号替换所有出现的等号。
  • 不是,这正是重点。这是一个结构体的字符串表示
  • 这听起来像是一个 XY 问题。这绝对是可解析的,但您应该显示返回它的代码,因为可能有一种方法可以获得对您有用的格式
  • @Cireo 使用返回此未解析字符串的代码示例更新了问题

标签: python pyspark


【解决方案1】:

至少您需要将 = 替换为 : 并用双引号括起来:

import json
import re

string = "{list=[{a=1}, {a=2}, {a=3}]}"
fixed_string = re.sub(r'(\w+)=', r'"\1":', string)
print(type(fixed_string), fixed_string)
parsed = json.loads(fixed_string)
print(type(parsed), parsed)

输出

<class 'str'> {"list":[{"a":1}, {"a":2}, {"a":3}]}
<class 'dict'> {'list': [{'a': 1}, {'a': 2}, {'a': 3}]}

【讨论】:

  • 很遗憾literal_eval 不允许使用dict,但您也可以使用eval(raw.replace('{', 'dict(').replace('}', ')'))
  • @Cireo,不,当有更安全的选择时,永远不要使用eval。另外,我很确定 'list' 只是一个任意键名,而不是 list 类型。无论哪种方式,都有比使用eval 更好的方法
  • @DeepSpace 确实只是一个任意键
【解决方案2】:

试试这个:

import re
import json  
data="{list=[{a=1}, {a=2}, {a=3}]}"
data=data.replace('=',':')
pattern=[e.group() for e in re.finditer('[a-z]+', data, flags=re.IGNORECASE)]
for e in set(pattern):
    data=data.replace(e,"\""+e+"\"")
print(json.loads(data))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多