Назначение нескольких строк файла нескольким переменным с помощью.readline() в цикле "для строки в данных"



Я пытаюсь использовать цикл for line in data:, чтобы назначить первые 3 строки файла 3 различным переменным (по одной строке для каждой переменной) и заставить его повторяться для каждых 3 строк, так что если бы в файле было 9 строк, каждая переменная содержала бы 3 разные строки на протяжении итераций, но я не могу понять, что это такое.



Пока мой базовый код выглядит примерно так:



for line in infile:

to_line = infile.readline()
from_line = infile.readline()
header_line = infile.readline()


, но это просто не работает. Он присваивает каждую вторую строку моего файла каждой переменной (то есть 4 строки для каждой переменной и не все строки назначаются).



Предпосылкой программы является обработка входного файла, содержащего 9 строк (строка" кому", строка" от "и строка" тема "для каждого письма [всего 3 письма]), а затем сортировка их на основе того, являются ли они спамом или" хорошей " почтой.

Липкое условие, которое у меня есть для этого, состоит в том, что это для курса колледжа, и мне не разрешено использовать что-либо, что мы еще не прошли в классе (мы 8 недель, поэтому мы не можем использовать это). иметь небольшую базу знаний базовой информации для использования). Если кто-нибудь ответит мне тем, что я не могу использовать, я дам вам знать.

780   5  

5 ответов:

Это не работает, потому что начало цикла (т. е. for line in infile:) читает следующую строку из infile, которую вы в основном выбрасываете, не используя ее. Альтернативой этому было бы чтение всех строк заранее в список, а затем работа через список:

# read all lines from the file into a list, where each list element is one line
lines = infile.readlines()

# iterate through the list three lines at a time, until you run out of lines
line_number = 0
while line_number < len(lines):
    to_line = lines[line_number]
    from_line = lines[line_number+1]
    header_line = lines[line_number+2]
    line_number += 3

На самом деле вам не нужно вызывать readline, достаточно просто перебрать файл. Вы можете использовать zip функция перегруппировки линий. Таким образом, общее решение будет выглядеть следующим образом:

for odd_line,even_line in zip(infile, infile):
     # Do something

Если вы хотите сначала создать список всех четных и нечетных строк (и это очень хорошая структура данных), вы можете просто добавить к списку, например:

odd_lines = []
even_lines = []
for odd_line,even_line in zip(infile, infile):
     odd_lines.append(odd_line)
     even_lines.append(even_line)

В качестве альтернативы используйте

lines = list(infile)

Чтобы получить список всех строк, а затем ломтики чтобы извлеките часть файла. Например,

even_lines = lines[1::2]
Другой альтернативой является использование итератора с циклом while. Просто позвоните next несколько раз. Например, здесь выводятся все нечетные строки:
iterator = iter(infile)
while True:
  try:
    odd_line = next(iterator)
    print(odd_line)
    even_line = next(iterator)
  except StopIteration:
    break

Если вы не хотите использовать break (и это сумасшедший ), Вы можете просто поймать исключение вне цикла:

iterator = iter(infile)
try:
  while True:
    odd_line = next(iterator)
    print(odd_line)
    even_line = next(iterator)
except StopIteration:
  pass # end of file reached

Вместо итератора можно также использовать readline:

odd_lines = []
even_lines = []
while True:
  line = infile.readline()
  if not line: # End of file reached
    break
  odd_lines.append(line)

  line = infile.readline()
  if not line: # End of file reached
    break
  even_lines.append(line)
Опять же, если вы действительно не можете использовать операторы break, вы может подделать их:
odd_lines = []
even_lines = []
go_on = True
while go_on:
  line = infile.readline()
  if even_line:
    odd_lines.append(line)
    line = infile.readline()
    if line:
      even_lines.append(line)
    else:
      go_on = False

Поскольку файлы являются итераторами,их можно разбить на группы. Это означает, что ответ на ваш вопрос - очень простой фрагмент кода:

with open(filename) as f:
    for to_line, from_line, header_line in zip(f, f, f):
        print (to_line, from_line, header_line)

Для студентов, которым не разрешено использовать zip , также будет работать следующее:

f = open(filename)
try:
    while True:
        to_line, from_line, header_line = next(f), next(f), next(f)
        print (to_line, from_line, header_line)
except StopIteration:
    pass
finally:
    f.close()

Каждая итерация цикла for считывает строку из infile в line. Попробуйте этот код:

for line in infile:
    print line

Это считывает каждую строку infile в line и печатает каждую line.

Таким образом, когда вы делаете infile.readline() внутри цикла, вы фактически читаете другую строку, так как первая была прочитана в line.

Легко запутаться, когда вы читаете for line in infile на английском языке, так как вы не понимаете, что это на самом деле означает: "прочитайте строку из infile в line и выполните код ниже. Сделай это и так до тех пор, пока не останется ни строчки, которую можно было бы прочесть."

Поскольку вы читаете только 3 строки за раз, вы можете сделать что-то вроде:
infile = open("yourfilename.txt")
for i in range(3):
   to_line = infile.readline()
   from_line = infile.readline()
   header_line = infile.readline()
   # Do something with the lines you just read

Этот цикл будет выполняться 3 раза (см. range(3)), каждый раз читая 3 строки в соответствующие переменные.

Это отличное применение для словаря списков. Таким образом, вы можете получить общее решение, которое будет возвращать словарь каждого индекса номера строки.

Сначала сгенерируем несколько строк:

with open('/tmp/lines.txt','w') as fw:
    for line in range(10):     # 0 - 9!!!
        print >>fw, 'This is line',line
Теперь считайте эти строки в структуру данных, в которой каждая n - я строка проиндексирована:
n=3        
with open('/tmp/lines.txt','r') as fr:
    i=0
    ells={i:[] for i in range(n)}
    for line in fr:
        ells[i%n].append(line.strip())
        i+=1

print ells

Comments

    Ничего не найдено.