【问题标题】:Converting an "If Else" statement to a JSON file将“If Else”语句转换为 JSON 文件
【发布时间】:2016-05-31 09:15:11
【问题描述】:

我有这个input,我们称之为tree

if ( device_type_id <= 1 )
    39 Clicks - 0.61%
    2135 Conversions - 33.32% 
else ( device_type_id > 1 )
    if ( country_id <= 216 )
        1097 Clicks - 17.12%
    else ( country_id > 216 )
        if ( browser_id <= 2 )
            296 Clicks - 4.62%
        else ( browser_id > 2 )
            if ( browser_id <= 4 )
                if ( browser_id <= 3 )
                    if ( operating_system_id <= 2 )
                        262 Clicks - 4.09%
                        1094 Impressions - 17.08%
                    else ( operating_system_id > 2 )
                        if ( operating_system_id <= 4 )
                            281 Clicks - 4.39%
                            220 Impressions - 3.43%
                        else ( operating_system_id > 4 )
                            if ( operating_system_id <= 6 )
                                4 Clicks - 0.06%
                                20 Impressions - 0.31%
                            else ( operating_system_id > 6 )
                                70 Impressions - 1.09%



                else ( browser_id > 3 )
                    if ( operating_system_id <= 2 )
                        19 Clicks - 0.3%
                        21 Impressions - 0.33%
                    else ( operating_system_id > 2 )
                        19 Clicks - 0.3%
                        707 Impressions - 11.03%


            else ( browser_id > 4 )
                113 Clicks - 1.76%

然后我使用tree 作为input 创建了这个函数:

def function_one(tree):
    network = []
    for line in tree.splitlines() : 
        if line.strip():
            line = line.strip()
            network.append(line)
        else : break
        if not line : break

    res = []
    res.append({'name':'Prediction Result', 'children':parser(network[1:])})
    with open('static/json/structure_sklearn.json', 'w') as outfile:
        json.dump(res, outfile)
    return tree

如您所见,我使用了parser 函数:

def parser(lines):
    block = []
    while lines :

        if lines[0].startswith('if'):
            bl = ' '.join(lines.pop(0).split()[1:]).replace('(', '').replace(')', '')
            block.append({'name':bl, 'children':parser(lines)})

            if lines[0].startswith('else'):
                be = ' '.join(lines.pop(0).split()[1:]).replace('(', '').replace(')', '')
                block.append({'name':be, 'children':parser(lines)})
        elif not lines[0].startswith(('if','else')):
            block2 = lines.pop(0)
            block.append({'name':block2})
        else:
            break   
    return block

我的问题是,我不知道我在哪个阶段错过了一些东西,因为从function_one 创建的json 文件只是:

[
   {
      "children":[
         {
            "name":"39 Clicks - 0.61%"
         },
         {
            "name":"2135 Conversions - 33.32%"
         }
      ],
      "name":"Prediction Result"
   }
]

【问题讨论】:

  • 您需要取消缩进以if lines[0].startswith("else") 开头的块。现在,如果该行以“if”开头,则它是代码的一部分,这意味着它永远不会被调用。这可能也希望成为elif 而不是if,但无论哪种方式都应该有效。此外,如果第一行不是ifelse,您只会弹出第一行。为什么要对线进行这种破坏性的迭代?只需for line in lines:
  • 我有一个嵌套的“if”语句,因为我想在 json 文件中创建一个嵌套结构,因此我使用了“while”和“破坏性迭代”,所以我可以访问下一行在“if”语句中并用“else”测试下一个,如果我使用“for”,我将有单独的语句。

标签: python json parsing


【解决方案1】:

这是我建议的修改:

def parser(lines):
    block = []
    while lines :

        if lines[0].startswith('if'):
            bl = ' '.join(lines.pop(0).split()[1:]).replace('(', '').replace(')', '')
            block.append({'name':bl, 'children':parser(lines)})

        elif lines[0].startswith('else'):
            be = ' '.join(lines.pop(0).split()[1:]).replace('(', '').replace(')', '')
            block.append({'name':be, 'children':parser(lines)})

        elif not lines[0].startswith(('if','else')):
            block2 = lines.pop(0)
            block.append({'name':block2})
        else:
            break   
    return block

通过此更改,我得到以下 JSON 缩进输出:

[
  {
    "name": "Prediction Result", 
    "children": [
      {
        "name": "39 Clicks - 0.61%"
      }, 
      {
        "name": "2135 Conversions - 33.32%"
      }, 
      {
        "name": " device_type_id > 1 ", 
        "children": [
          {
            "name": " country_id <= 216 ", 
            "children": [
              {
                "name": "1097 Clicks - 17.12%"
              }, 
              {
                "name": " country_id > 216 ", 
                "children": [
                  {
                    "name": " browser_id <= 2 ", 
                    "children": [
                      {
                        "name": "296 Clicks - 4.62%"
                      }, 
                      {
                        "name": " browser_id > 2 ", 
                        "children": [
                          {
                            "name": " browser_id <= 4 ", 
                            "children": [
                              {
                                "name": " browser_id <= 3 ", 
                                "children": [
                                  {
                                    "name": " operating_system_id <= 2 ", 
                                    "children": [
                                      {
                                        "name": "262 Clicks - 4.09%"
                                      }, 
                                      {
                                        "name": "1094 Impressions - 17.08%"
                                      }, 
                                      {
                                        "name": " operating_system_id > 2 ", 
                                        "children": [
                                          {
                                            "name": " operating_system_id <= 4 ", 
                                            "children": [
                                              {
                                                "name": "281 Clicks - 4.39%"
                                              }, 
                                              {
                                                "name": "220 Impressions - 3.43%"
                                              }, 
                                              {
                                                "name": " operating_system_id > 4 ", 
                                                "children": [
                                                  {
                                                    "name": " operating_system_id <= 6 ", 
                                                    "children": [
                                                      {
                                                        "name": "4 Clicks - 0.06%"
                                                      }, 
                                                      {
                                                        "name": "20 Impressions - 0.31%"
                                                      }, 
                                                      {
                                                        "name": " operating_system_id > 6 ", 
                                                        "children": [
                                                          {
                                                            "name": "70 Impressions - 1.09%"
                                                          }
                                                        ]
                                                      }
                                                    ]
                                                  }
                                                ]
                                              }
                                            ]
                                          }
                                        ]
                                      }
                                    ]
                                  }
                                ]
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]

我无法判断这是否是您正在寻找的实际形式或输出,但它似乎包含原始树源中的所有节点。

编辑:

这是一种使用迭代器遍历行列表的更简洁(并且可能更快)的方法。

def parser(lines):
    lines_iter = iter(lines)
    block = []
    for line in lines_iter:

        if line.startswith('if'):
            bl = ' '.join(line.split()[1:]).replace('(', '').replace(')', '')
            block.append({'name':bl, 'children':parser(lines_iter)})

        elif line.startswith('else'):
            be = ' '.join(line.split()[1:]).replace('(', '').replace(')', '')
            block.append({'name':be, 'children':parser(lines_iter)})

        elif not line.startswith(('if','else')):
            block2 = line
            block.append({'name':block2})
        else:
            break   
    return block

我将function_one中的调用改为调用parser(network)而不是parser(network[1:]),但其余代码不变。 list.pop(0) 很慢,尤其是对于大型列表,因为底层数组必须将每个元素向下移动一个。

【讨论】:

  • 这正是我正在寻找的输出!
猜你喜欢
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-04
相关资源
最近更新 更多