【问题标题】:Convert and slice Python string to list?将 Python 字符串转换并切片为列表?
【发布时间】:2018-03-16 04:14:51
【问题描述】:

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

【问题讨论】:

  • 嗨。您是否尝试过使用 eval()?你可以试试这个: st_new=eval(st) 然后打印 st_new。我希望这有效。!
  • 嗨!这不起作用@ShrinivasDeshmukh data/policy/line[Type="BusinessOwners"]/risk/coverage[Type="FuelHeldForSale"]/id ^ SyntaxError: invalid syntax
  • 请参考这个链接,类似的问题已经在这里讨论过:stackoverflow.com/questions/36068779/…
  • @mdeonte001 --- 如果您希望人们利用他们的时间来解决您的问题,您应该更具体地说明您想要什么。如果你想在你的列表中找到一本字典,那就说明它而不是让别人读你的想法!
  • @MichaelSwartz 请参见上文,我声明“包含字典的列表..”,在我的示例中,我显示了字典。

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


【解决方案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']

【讨论】:

  • 嗨,我运行了这个,我得到了错误 AttributeError: 'str' object has no attribute 'literal_eval' - ast.literal_eval(item) 应该是 st.literal 吗?
  • 对不起。你需要先导入 ast 。请再次检查。
  • 不是很喜欢使用literal_eval,但这要好得多。
  • 这行得通!谢谢你。 @MadPhysicist 关心分享你为什么不喜欢literal_eval?
  • 它确实有效。由于this gist 之类的原因,我对literal_eval 持谨慎态度。我不能 100% 确定它是否可以完全用 literal_eval 完成,但我宁愿不冒险。
【解决方案2】:

如果不是 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']

【讨论】:

    【解决方案3】:

    让我们一行完成:

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

    【讨论】:

      【解决方案4】:

      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]

      【讨论】:

        猜你喜欢
        • 2018-09-15
        • 2021-03-02
        • 1970-01-01
        • 2021-07-25
        • 1970-01-01
        • 2015-04-14
        • 2016-11-09
        • 1970-01-01
        • 2023-03-16
        相关资源
        最近更新 更多