正如@ajon指出,我不認爲有什麼根本性的錯誤代碼,除了縮進。隨着固定的縮進,它適用於我。但是有一些改進的機會。
1)在Python中,迭代事物的標準方法是使用for
loop。當使用for
循環時,您不需要定義循環計數器變量並自己跟蹤它們以迭代事物。相反,你寫這樣的東西
for line in lines:
print line
遍歷字符串列表中的所有項目並打印它們。
2)在大多數情況下,這就是您的for
循環的樣子。但是,在某些情況下,您確實需要跟蹤循環計數。你的情況就是這樣的情況,因爲你不僅需要這一行,而且還需要這三行,因此需要使用計數器進行索引(lst[i]
)。爲此,有enumerate()
,它將返回項目列表和其索引,然後您可以循環。
for i, line in enumerate(lines):
print i
print line
print lines[i+7]
如果你要手動跟蹤循環計數器在您的例子中,有兩件事情:
3)這i = i+1
應移出if
和else
塊。你在這兩種情況下都這樣做,所以把它放在if/else
之後。在你的情況else
塊則沒有做任何事,而且可以消除:
while i < 500:
if Lines[i] == searchquery:
f2.write(Lines[i])
f2.write(Lines[i+1])
f2.write(Lines[i+2])
i = i+1
4)現在,這將導致IndexError
比500線較短的文件。而不是硬編碼循環計數500,您應該使用您正在迭代的序列的實際長度。 len(lines)
會給你那麼長的時間。但不是使用while
循環,而是使用for
循環和range(len(lst))
來重複範圍從零到len(lst) - 1
的列表。
for i in range(len(lst)):
print lst[i]
5)open()
可以用作context manager這需要關閉文件你的照顧。上下文管理器是一個相當先進的概念,但是如果它們已經爲您提供,使用起來非常簡單。通過做這樣的事情
with open('test.txt') as f:
f.write('foo')
該文件將被打開,並訪問您的f
是with
塊內。離開程序塊後,文件將自動關閉,所以最終不會忘記關閉文件。
在你的情況下,你打開兩個文件。這可以通過只使用兩個with
語句和嵌套來完成他們
with open('one.txt') as f1:
with open('two.txt') as f2:
f1.write('foo')
f2.write('bar')
,或者在Python 2.7/Python的3.x中,通過在單一with
聲明嵌套兩次上下文經理:
with open('one.txt') as f1, open('two.txt', 'a') as f2:
f1.write('foo')
f2.write('bar')
6)根據創建文件的操作系統,行結束是不同的。在類似UNIX的平臺上,它是\n
,OS X使用之前的Macs \r
,而Windows使用\r\n
。因此,Lines[i] == searchquery
將不匹配Mac或Windows行尾。 file.readline()
可以處理所有這三個,但因爲它保留了行結束處的所有行結束符,所以比較將失敗。
searchquery = 'am'
# ...
if line.strip() == searchquery:
# ...
(閱讀使用file.read()
文件和:這是通過使用str.strip()
,這將剝離開頭和末尾的所有空格的字符串,比較搜索模式沒有結束,以該行解決使用str.splitlines()
將是另一種選擇。)
但是,既然你提到你的搜索字符串實際上出現在一行的開頭,讓我們做到這一點,利用str.startswith()
:
if line.startswith(searchquery):
# ...
7)官方風格指南的Python,PEP8,建議使用CamelCase
作爲類別,lowercase_underscore
作爲幾乎所有其他事物(變量,函數,屬性,方法,模塊,包)。因此,而不是Lines
使用lines
。與其他人相比,這絕對是一個小問題,但仍然值得在早期進行。
因此,考慮到所有這些事情,我會寫你這樣的代碼:
searchquery = 'am'
with open('Test.txt') as f1:
with open('Output.txt', 'a') as f2:
lines = f1.readlines()
for i, line in enumerate(lines):
if line.startswith(searchquery):
f2.write(line)
f2.write(lines[i + 1])
f2.write(lines[i + 2])
由於@TomK指出,所有這些代碼假設,如果你的搜索字符串匹配,有至少兩條線跟着它。如果你不能依靠這個假設,那麼通過使用像@poorsod這樣的try...except
塊來處理這種情況是正確的。
在第二個例子中,它看起來像你的循環體沒有縮進..是複製/粘貼錯誤還是你實際上有什麼? – Collin
您可能應該查看'enumerate'函數和'for iterable'構造。 –
@Collin你是對的問題是縮進。我可能看了兩個小時的代碼,從未注意到!謝謝! – Andreanna