正如@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