2014-01-15 3 views
1

У меня возникли проблемы с использованием next() и strip(), чтобы получить строку, следующую за той, которую я читаю. Данные теста выглядит примерно так:Получение следующей строки с использованием python next() и strip()

@abcde:111/2 
ABCDEFGHIj 
+abcde:111/2 
bla11 
@abcde:115/2 
JDIJSKNDIJ 
+abcde:115/2 
bla13 
@abcde:113/2 
djijwkoken 
+abcde:113/2 
bla15 

Моя цель состоит в том, чтобы удалить все наборы из 4-х строк, начиная с «@», которые содержат «N» во второй строке. Ожидаемый результат теста должен выглядеть следующим образом:

@abcde:111/2 
ABCDEFGHIj 
+abcde:111/2 
bla11 
@abcde:113/2 
djijwkoken 
+abcde:113/2 
bla15 

Вот мой код (delete_N.py), я бегу его с помощью Mac OS терминал на удаленном сервере Ubuntu, с Python 2.7:

import sys 

filename1 = sys.argv[1] #file to process 

data = open(filename1, 'r') 

def del_N(input1): 
    for line in input1: 
     if line[:1] == '@' and 'N' not in next(input1).strip(): 
      print line.strip() 
      for i in range(3): 
       print next(input1).strip() 

del_N(data) 

Но я получаю следующее сообщение об ошибке:

Traceback (most recent call last): 
    File "delete_N.py", line 14, in <module> 
    del_N(data) 
    File "delete_N.py", line 12, in del_N 
    print next(input1).strip() 
StopIteration 

Что я делаю неправильно?

ответ

3

В вашей программе вы перечитываете данные из файла. Проверьте Lego's answer, где он объясняет ошибку очень четко.

Вы можете сделать это вот так. Эта программа предполагает, что количество строк в файле кратно 4.

with open("Input.txt", "r") as input_file: 
    for line1 in input_file: 
     line2, line3, line4 = [next(input_file) for _ in xrange(3)] 
     if "N" not in line2: 
      print line1 + line2 + line3 + line4.rstrip() 

Выход

@abcde:111/2 
ABCDEFGHIj 
+abcde:111/2 
bla11 
@abcde:113/2 
djijwkoken 
+abcde:113/2 
bla15 
2

Python создает исключение StopIteration, когда вы достигаете конца итератора. Если вы вызываете next() на итераторе вручную, а не используете цикл for ... in ... (который будет завершен, когда будет поднят StopIteration), вы должны: должен уловить StopIteration и обработать его, потому что это означает, что ... ну, итератор остановился ,


Во всяком случае, здесь (ИМО) чистое решение:

data = ... # your data goes here, from a file or whatever 
lines = data.split('\n') 
n = 4 
groups = zip(*[lines[i::n] for i in range(n)]) 
# or, groups = zip(lines[0::4], lines[1::4], lines[2::4], lines[3::4]) 
result = [] 

for group in groups: 
    if group[0].startswith('@') and 'N' in group[1]: 
     continue # i.e. don't append 
    else: 
     result.append(group) 

joined_result = '\n'.join(['\n'.join(group) for group in result]) 
print(joined_result) 

Результат:

@abcde:111/2 
ABCDEFGHIj 
+abcde:111/2 
bla11 
@abcde:113/2 
djijwkoken 
+abcde:113/2 
bla15 
+1

Я обычно использую 'continue', где вы использовали' pass'. 'continue' будет работать независимо от того, как выглядит остальная часть цикла. В этом случае остальная часть цикла является 'else:' case, поэтому 'pass' работает. Во всяком случае, я согласен, что это путь, а не использование 'next()'. – steveha

+0

@steveha Хорошая точка, 'continue' действительно стилистически лучше здесь. Починю. – senshin

+0

@steveha Почему 'continue' лучше, чем' pass' или 'next()'? Я имею в виду, в каких ситуациях цикл не будет работать? – biohazard

2

Проблема заключается в том, что в то же время, как вы перебор файла с цикл for, next также выполняет итерацию курсора при его перемещении по файлу. Это означает, что на каждой итерации вы фактически прыгаете пятен за раз.

Например, посмотрите на этот файл:

   openning the file 
@abcde:111/2 for line in input1: # First iteration. 
ABCDEFGHIj   if line[:1] == '@' and 'N' not in next(input1).strip(): 
+abcde:111/2   print next(input1).strip() 
bla11   for line in input1: # Second iteration. 
@abcde:115/2  etc... 

Смотрите, как на каждой итерации до 3-х линий прыгали, поэтому, когда второй последний или последние строки в итерации встречаются, она будет переливаться и поднять ошибка StopIteration.

Смежные вопросы