将列表列表的字符串表示形式转换为不带eval的列表python

2024-06-01 05:17:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这个:

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,但我不知道怎么用


Tags: 字符串列表evalastsifnavliteralhes
3条回答

在我看来,您需要在这里编写自己的小解析器,例如:

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


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

我承认这是一个非常僵硬和有限的答案,因为它只适用于基于示例文本的给定信息:

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. 单个字符串中没有括号或单/双引号

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

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

相关问题 更多 >