什么是从Python文件中读取内容的更好方法?

时间:2011-10-24 11:05:08

标签: python parsing multiline

这是我的python文件: -

TestCases-2
Input-5
Output-1,1,2,3,5
Input-7
Ouput-1,1,2,3,5,8,13

我想要的是: -

  • 变量test_no = 2(测试用例数)
  • 列表testCaseInput = [5,7]
  • 列表testCaseOutput = [[1,1,2,3,5],[1,1,2,3,5,8,13]]

我试过这样做:

               testInput = testCase.readline(-10)

        for i in range(0,int(testInput)):
            testCaseInput = testCase.readline(-6)
            testCaseOutput = testCase.readline(-7)

下一步是在(',')的基础上删除数字,然后将它们放入列表中。

奇怪的是,readline(-6)没有给出理想的结果。

有没有更好的方法来做到这一点,显然我错过了。

我不介意在这里使用序列化,但是我想让某人编写一个我已经显示的文本文件然后从中获取数据非常简单。怎么做?

4 个答案:

答案 0 :(得分:2)

我不确定我是否完全遵循你要做的事情,但我想我会尝试这样的事情:

testCaseIn = [];
testCaseOut = [];

for line in testInput:
    if (line.startsWith("Input")):
        testCaseIn.append(giveMeAList(line.split("-")[1]));
    elif (line.startsWith("Output")):
        testCaseOut.append(giveMeAList(line.split("-")[1]));

其中giveMeAList()是一个以逗号分隔的数字列表的函数,并从中生成一个数据集列表。

我没有测试这段代码,但是当我想要在过去编写配置文件时,我编写了使用这种结构的东西。

答案 1 :(得分:2)

readline 方法的负参数指定要读取的字节数。我不认为这是你想做的事。

相反,使用 readlines()将所有内容同时拉入列表更简单:

with open('data.txt') as f:
    full_lines = f.readlines()

# parse full lines to get the text to right of "-"
lines = [line.partition('-')[2].rstrip() for line in full_lines]

numcases = int(lines[0])
for i in range(1, len(lines), 2):
    caseinput = lines[i]
    caseoutput = lines[i+1]
    ...

这里的想法是分离关注点(数据的来源,' - '的解析,以及如何处理案例的业务逻辑)。这比在每一步都有 readline()和冗余解析逻辑更好。

答案 2 :(得分:1)

  1. 此行有错误:

    Ouput-1,1,2,3,5,8,13  // it should be 'Output' not 'Ouput
    
  2. 这应该有效:

    testCase = open('in.txt', 'r')
    testInput = int(testCase.readline().replace("TestCases-",""))
    for i in range(0,int(testInput)):
        testCaseInput = testCase.readline().replace("Input-","")
        testCaseOutput = testCase.readline().replace("Output-","").split(",")
    

答案 3 :(得分:1)

您可以使用正则表达式,这样可以更轻松。请参阅问题:python: multiline regular expression

对于您的情况,请尝试:

import re
s = open("input.txt","r").read()
(inputs,outputs) = zip(*re.findall(r"Input-(?P<input>.*)\nOutput-(?P<output>.*)\n",s))

然后根据需要split(",")每个输出元素

如果您这样做,您将获得不需要输入文件中第一行的好处,因此您无需事先指定您有多少条目。

你也可以从上面的代码中取出解压缩(即zip(*...)),然后你可以处理每个输入并一次输出一对。我的猜测实际上就是你想要做的事情。

编辑想要提供我当时的意思的完整示例。我假设这是一个测试脚本所以我会说使用模式匹配迭代器的力量来帮助保持你的代码更短更简单:

for (input,output) in re.findall(r"Input-(?P<input>.*)\nOutput-(?P<output>.*)\n",s):
  expectedResults = output.split(",")

  testResults = runTest(input)
  // compare testResults and expectedResults ...