将包含字符串和嵌套字符串列表的列表拆分成一个平面列表

7
我正在编写一个处理文件中字符串的程序。我想要简单地将文字(例如SUB =X'1D'这样的字符串,可以组装成=X'1D' BYTE X'1D')添加到测试文件中在 ' LTORG' 上方。
问题是我将每个LTORG上方收集的文字作为列表插入,而我想逐个插入文字。 我有以下输出:
[' START 100', " SUB =X'1D'", ' LTORG', '["=X\'1D\' BYTE X\'1D\'"]', ' RESW 
   20', " SUB =X'0259'", " ADD =C'12345'", " MUL =X'4356'", " SUB =X'69'", ' 
   LTORG', '["=X\'0259\' BYTE X\'0259\'", "=C\'12345\' BYTE C\'12345\'", 
   "=X\'4356\' BYTE X\'4356\'", "=X\'69\' BYTE X\'69\'"]', " ADD =C'05'", ' 
   END EXA']

def handle_LTORG(self, testfile):

    myfile.testfile = testfile

    for index, line in enumerate(myfile.testfile):
        line = line.split(" ", 3)
        if len(line) > 2:
            if line[2].startswith("=X") or line[2].startswith("=C"):
                raw_literal = line[2]
                instruction = 'BYTE'
                operand = line[2][1:]
                literal = [raw_literal, instruction, operand]
                literal = ' '.join(literal)
                myfile.literals.append(literal)
        if line[1] == 'LTORG':
            if myfile.literals is not None:
                myfile.testfile.insert(index + 1, str(myfile.literals))
                myfile.literals.pop(0)

第二行代码是主要的问题所在。它将收集的字面量添加到一个列表中,并将它们作为压缩的列表插入,而不是每行一个字符串。
我希望它看起来像这样:
[' START 100', " SUB =X'1D'", ' LTORG', '"=X'1D' BYTE X'1D'"', ' RESW 20', " SUB =X'0259'", " ADD =C'12345'", " MUL =X'4356'", " SUB =X'69'", ' LTORG', '"=X'0259' BYTE X'0259'", "=C'12345' BYTE C'12345'", "=X'4356' BYTE X'4356'", "=X'69' BYTE X'69'", " ADD =C'05'", ' END EXA']

testfile的类型是什么?(因此,myfile.testfile的类型是什么?) - TrebledJ
此外,为什么不使用 if myfile.literals: 而不是 if myfile.literals is not None: - TrebledJ
3个回答

1

我会尝试使用类似这里如何将列表中的列表变成平面列表?的顶级评论中的方法。

list = ['whatever',['1','2','3'],'3er']
flat_list = []
for member in list:
    if type(member) is list:
        for item in member:
            flat_list.append(item)
    else:
        flat_list.append(member)

这并没有解决我所遇到的两个问题中的任何一个。我不想要一个纯粹的平面列表,我需要像输出一样的格式。 - asultan904

1

你要做的是两个操作的组合:

  • 首先,你需要使用literal_evalast模块将所有在字符串文字中的列表转换为实际列表。

  • 然后,你需要展开列表。

下面是演示该过程的代码:

from ast import literal_eval
inlist = [' START 100', " SUB =X'1D'", ' LTORG', '["=X\'1D\' BYTE X\'1D\'"]', ' RESW    20', " SUB =X'0259'", " ADD =C'12345'", " MUL =X'4356'", " SUB =X'69'", '    LTORG', '["=X\'0259\' BYTE X\'0259\'", "=C\'12345\' BYTE C\'12345\'",    "=X\'4356\' BYTE X\'4356\'", "=X\'69\' BYTE X\'69\'"]', " ADD =C'05'", '    END EXA']
inlist = [literal_eval(elem) if elem[0] == '[' and elem[-1] == ']' else elem for elem in inlist]
outlist = []
for elem in inlist:
     if isinstance(elem,list):
          for item in elem:
               outlist.append(item)
     else:
          outlist.append(elem)
print(outlist)

输出:

[' START 100', " SUB =X'1D'", ' LTORG', "=X'1D' BYTE X'1D'", ' RESW    20', " SUB =X'0259'", " ADD =C'12345'", " MUL =X'4356'", " SUB =X'69'", '    LTORG', "=X'0259' BYTE X'0259'", "=C'12345' BYTE C'12345'", "=X'4356' BYTE X'4356'", "=X'69' BYTE X'69'", " ADD =C'05'", '    END EXA']

第二个“LTORG”之后的另外两个文字常量去哪了?请将它们作为单独的逗号分隔字符串提取出来。 - asultan904
@A.Sultan编辑了我的答案。现在它应该返回正确的结果。 - Vasilis G.

0

更新:使用 while 循环解决了问题。欢迎提出建议!

    def handle_LTORG(self, testfile):

    myfile.testfile = testfile

    for index, line in enumerate(myfile.testfile):
        line = line.split(" ", 3)
        if len(line) > 2:
            if line[2].startswith("=X") or line[2].startswith("=C"):
                raw_literal = line[2]
                instruction = 'BYTE'
                operand = line[2][1:]
                literal = [raw_literal, instruction, operand]
                literal = ' '.join(literal)
                myfile.literals.append(literal)
        if line[1] == 'LTORG':
            if myfile.literals:
                i = 'hi'
                while len(i) > 0:
                    i = myfile.literals[-1]
                    myfile.testfile.insert(index+1, str(i))
                    myfile.literals.pop()
                    if len(myfile.literals) == 0:
                        break

    return myfile.testfile

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接