将Python字符串转换并切片到列表?

时间:2018-03-16 04:14:51

标签: python json python-3.x oop apache-spark

我获得了一个原始字符串,它是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'}

4 个答案:

答案 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']

[IDEOne Link]

我个人喜欢将代码的功能拆分为功能的管道。在这种情况下,我会让主循环根据返回拆分元素替换的函数累积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

[IDEOne Link]

答案 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']