Какой лучший способ чтения строк из файла Python? - PullRequest
3 голосов
/ 24 октября 2011

Это мой файл 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 ]

2 голосов
/ 24 октября 2011

Отрицательный аргумент метода 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 голосов
/ 24 октября 2011

Я не уверен, что точно следую тому, что вы пытаетесь сделать, но, наверное, я бы попробовал что-то вроде этого:

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 голос
/ 24 октября 2011

Вы можете использовать регулярные выражения для этого, и это делает это намного проще. Смотрите вопрос: python: многострочное регулярное выражение

В вашем случае попробуйте это:

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 ...
1 голос
/ 24 октября 2011
  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(",")
    
...