Чтение ввода из файла в Python 3.x
Скажем, вы читаете ввод из файла, структурированного так
P3
400 200
255
255 255 255
255 0 0
255 0 0
etc...
Но вы хотите учесть любые ошибки, которые могут возникнуть из входного файла, как в
P3 400
200
255
255 255
255
255 0 0
255 0
0
etc...
Я хочу прочитать в первом токене "P3", затем в следующих двух "400", "200" (высота / ширина) "255", и с этого момента я хочу прочитать каждый токен и объяснить, как они должны быть в группы из 3. У меня есть правильный код для чтения этой информации, но я не могу преодолеть стену, пытаясь понять, как читать информацию по токену, а не по строке.
Который не учитывает несовершенный ввод.
2 ответа
Вот один из способов сделать это, используя csv
модуль:
import csv
first_four = []
all_of_the_tokens = []
first_four_processed = False
with open('token') as token_file:
csv_reader = csv.reader(token_file, delimiter=' ')
for row in csv_reader:
all_of_the_tokens.extend(row)
if not first_four_processed:
first_four.extend(row)
if len(first_four) >= 4 and not first_four_processed:
first_four_processed = True
first_four = first_four[:4]
token_file.close()
rest_of_the_tokens = all_of_the_tokens[4:]
for i in range(0, len(rest_of_the_tokens), 3):
print rest_of_the_tokens[i:i+3]
Если ваш файл состоит из групп из трех значений (после первого P3
пункт), и вы не можете полагаться на разрывы строк, чтобы правильно сгруппировать их, я предлагаю прочитать файл как одну строку и выполнить разбиение и группировку самостоятельно. Вот прямой путь:
with open(filename) as f:
text = f.read() # get the file contents as a single string
tokens = text.split() # splits the big string on any whitespace, returning a list
it = iter(tokens) # start an iterator over the list
prefix = next(it) # grab the "P3" token off the front
triples = list(zip(it, it it)) # make a list of 3-tuples from the rest of the tokens
С помощью zip
при нескольких ссылках на один и тот же итератор ключевой трюк здесь. Если вам нужно обрабатывать группы других размеров с помощью того же кода, вы можете использовать zip(*[it]*grouplen)
,
Обратите внимание, что это отбросит любые оставшиеся значения в конце файла, если они не образуют группу из трех. Если вам нужно по-другому справиться с этой ситуацией, я предлагаю использовать zip_longest
от itertools
модуль, а не обычный zip
функция. (См. grouper
рецепт в itertools
документация.)