我获得了一个原始字符串,它是JSON中字符串的路径或“方向”。 我需要将以下字符串转换为包含字典的列表..
st = """data/policy/line[Type="BusinessOwners"]/risk/coverage[Type="FuelHeldForSale"]/id"""
列表应如下所示
paths = ['data','policy','line',{'Type':'BusinessOwners'},'risk','coverage',{"Type":"FuelHeldForSale"},"id"]
然后我遍历此列表以查找JSON中的对象(在Spark RDD中)
我试图st.split(\)
给了我
st.split('/')
Out[370]:
['data',
'policy',
'line[Type="BusinessOwners"]',
'risk',
'coverage[Type="FuelHeldForSale"]',
'CalculationDisplay']
但是,如何将'line[Type="BusinessOwners"]'
等项目转换为'line',{'Type':'BusinessOwners'}
?
答案 0 :(得分:1)
如果它不是1班轮,会更有效率,但我会让你从这里弄明白。如果您的输入变化超过给定的模式,可能想要一个更强大的基于正则表达式的解析引擎。或者只使用像JSON这样的标准化数据模型。
[word if '=' not in word else {word.split('=')[0]:word.split('=')[1]} for word in re.split('[/\[]', st.replace(']','').replace('"',''))]
['data','policy','line',{'Type':'BusinessOwners'},'risk', 'coverage',{'Type':'FuelHeldForSale'},'id']
答案 1 :(得分:1)
import json
first_list = st.replace('[', '/{"').replace(']', '}').replace('="', '": "').split('/')
[item if not "{" in item else json.loads(item) for item in first_list]
或使用ast.literal_eval
import ast
[item if not "{" in item else ast.literal_eval(item) for item in first_list]
out:
['data',
'policy',
'line',
{'Type': 'BusinessOwners'},
'risk',
'coverage',
{'Type': 'FuelHeldForSale'},
'id']
答案 2 :(得分:0)
Regular expressions可能是一个很好的工具。看起来您希望使用`text1,{text2:text3}转换看起来像text1[text2="text3"]
的元素。正则表达式看起来像这样:
(\w+)\[(\w+)=\"(\w+)\"\]
您可以通过多种方式修改此表达式。例如,您可以使用\w+
以外的名称作为名称,并插入\s*
以允许可选的空格。
接下来要记住的是,当您找到匹配项时,需要扩展列表。最简单的方法是创建一个新列表并append/extend:
import re
paths = []
pattern = re.compile(r'(\w+)\[(\w+)=\"(\w+)\"\]')
for item in st.split('/'):
match = pattern.fullmatch(item)
if match:
paths.append(match.group(1))
paths.append({match.group(2): match.group(3)})
else:
paths.append(item)
这会使paths
成为
['data', 'policy', 'line', {'Type': 'BusinessOwners'}, 'risk', 'coverage', {'Type': 'FuelHeldForSale'}, 'id']
我个人喜欢将代码的功能拆分为功能的管道。在这种情况下,我会让主循环根据返回拆分元素替换的函数累积paths
列表:
def get_replacement(item):
match = pattern.fullmatch(item)
if match:
return match.group(1), {match.group(2): match.group(3)}
return item,
paths = []
for item in st.split('/'):
paths.extend(get_replacement(item))
return item,
中的逗号非常重要。它将返回值转换为元组,因此您可以在函数返回的任何内容上使用extend
。
答案 3 :(得分:0)
让我们一行:
import re
pattern=r'(?<=Type=)\"(\w+)'
data="""data/policy/line[Type="BusinessOwners"]/risk/coverage[Type="FuelHeldForSale"]/id"""
print([{'Type':re.search(pattern,i).group().replace('"','')} if '=' in i else i for i in re.split('\/|\[',data)])
输出:
['data', 'policy', 'line', {'Type': 'BusinessOwners'}, 'risk', 'coverage', {'Type': 'FuelHeldForSale'}, 'id']