2014-01-15 42 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),我跑它遠程Ubuntu服務器上使用Mac OS的終端,與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被引發時終止),那麼你必須需要 catch StopIteration並處理它,因爲它意味着......好吧,迭代器已經停止。


不管怎麼說,這是一個(IMO)清潔的解決方案:

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

我通常使用,你使用''pass' continue'。無論循環的其他部分如何,「continue」都可以工作。在這種情況下,循環的其餘部分是'else:'case,所以'pass'起作用。無論如何,我同意這是要走的方式,而不是使用'next()'。 – steveha

+0

@steveha好點,'繼續'在這裏的確在風格上更好。將解決。 – 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錯誤。