【问题标题】:Convert string representation of list of lists to list of list python without eval将列表列表的字符串表示形式转换为没有 eval 的列表 python 列表
【发布时间】:2020-09-08 04:57:33
【问题描述】:

我有这个:

x = "[['ATRM', 'SIF', 'NWPX'], ['NAV','SENEA'], ['HES','AGYS', 'CBST', 'GTIM', 'XRSC']]"

x 是一个字符串。 我想要这个:

x = [['ATRM', 'SIF', 'NWPX'], ['NAV','SENEA'], ['HES','AGYS', 'CBST', 'GTIM', 'XRSC']]

x 是一个列表。

我通常会使用evalast.literal_eval,但这些功能不可用。有任何想法吗?也许我可以使用re,但我不知道如何。

【问题讨论】:

  • 而正是为什么这些功能不可用?它们的存在是有原因的——这是一些家庭作业吗?你可以自己实现一个解析器函数。
  • 这些函数在 Quantopian 上被列入黑名单,试图绕过它们。
  • 到目前为止您尝试过什么?您可以使用哪些功能
  • 一些 split() 函数应该这样做......
  • re.findall(r'"\s*([^"]*?)\s*"', x) 类似的东西会很好用,但是这个解决方案返回一个空列表

标签: python list regular-language re


【解决方案1】:

这是一个奇怪的解决方法,但如果您将单引号替换为双引号,则始终可以使用 json 解析器。

>>> import json
>>> json.loads(x.replace("'", '"'))
[['ATRM', 'SIF', 'NWPX'], ['NAV', 'SENEA'], ['HES', 'AGYS', 'CBST', 'GTIM', 'XRSC']]

【讨论】:

  • 不错的收获 - ++。
  • 好主意,但 json 也被列入黑名单:/
  • @Ch3steR 不起作用,返回没有 [] 的字符列表,但是是的,列表理解就是这个想法。
  • @Ch3steR 不太好用,第一个元素是字符串,而预期是另一个列表。你快到了
  • @Jan 同意,写解析器应该是 IMO 的首选,ast.literal_evaleval 应该是最后的手段。
【解决方案2】:

我承认这是一个非常笨拙且限制性的答案,因为它仅适用于基于示例文本的给定信息:

def list_list_str_to_list(data_str):
    final_word_list_list = []
    for temp_list_as_str in data_str.split("],"):
        final_word_list = []
        for raw_word in temp_list_as_str.split(","):
            new_word = raw_word
            for letter in "[],'\"":
                new_word = new_word.replace(letter, "")
            final_word_list.append(new_word)
        final_word_list_list.append(final_word_list)
    return final_word_list_list


def main():
    data_str = "[['ATRM', 'SIF', 'NWPX'], ['NAV','SENEA'], ['HES','AGYS', 'CBST', 'GTIM', 'XRSC']]"

    for final_word_list in list_list_str_to_list(data_str):
        print(final_word_list)


main()

它的主要思想是,当存在“]”的实例时,您可以通过拆分字符串来判断列表结束。大部分代码只是通过删除不需要的尾随字符(如括号、引号和空格)来清理单词。重申一下,这只有在以下情况下才有效:

  1. 字符串是仅表示二维列表的字符串,并且
  2. 单个字符串中没有括号或单/双引号

【讨论】:

    【解决方案3】:

    好的,我认为使用 re 找到了答案。

    x = "[['ATRM', 'SIF', 'NWPX'], ['NAV','SENEA'], ['HES','AGYS', 'CBST', 'GTIM', 'XRSC']]"
    
    y = [re.findall(r"\[(.+?)\]", x[1:])[i] for i in range(x.count('[')-1)]
    
    answer = [re.findall(r"'(.+?)'", y[i]) for i in range(len(y))]
    

    【讨论】:

      【解决方案4】:

      Imo,你需要在这里编写自己的小解析器,例如:

      def tokenizer(string):
          buffer = ""
          quote = False
          for c in string:
              if quote:
                  if c == "'":
                      yield ("VALUE", buffer)
                      buffer = ""
                      quote = not quote
                  else:
                      buffer += c
              else:
                  if c == "[":
                      yield ("LIST_OPEN", None)
                  elif c == "]":
                      yield ("LIST_CLOSE", None)
                  elif c == "'":
                      quote = not quote
                  else:
                      pass
      
      
      def parser(tokens):
          lst = []
          for token in tokens:
              x, y = token
              if x == "LIST_OPEN":
                  lst.append(parser(tokens))
              elif x == "LIST_CLOSE":
                  return lst
              elif x == "VALUE":
                  lst.append(y)
          return lst[0]
      

      带有一些测试断言:

      assert parser(tokenizer("['HES', ['ATRM', 'SIF', 'NAV']]")) == ['HES', ['ATRM', 'SIF', 'NAV']]
      assert parser(tokenizer("[['ATRM', 'SIF', 'NWPX'], ['NAV','SENEA'], ['HES','AGYS', 'CBST', 'GTIM', 'XRSC']]")) == [['ATRM', 'SIF', 'NWPX'], ['NAV','SENEA'], ['HES','AGYS', 'CBST', 'GTIM', 'XRSC']]
      


      这个想法是首先将您的字符串标记为值和命令,然后将其转换为实际列表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-04
        • 2017-11-24
        • 2021-04-13
        相关资源
        最近更新 更多