而不是解释为什么你的代码doe无法工作以及如何解决它(因为Tim Pietzcker已经做了令人钦佩的工作),我将解释如何编写代码,以便这样的问题不会出现在第一位。
试图编写自己的显式循环,检查和索引变量很困难且容易出错。这就是为什么Python给你提供很好的工具,几乎总是不需要这样做。这就是为什么你在使用Python,而不是C.
例如,看看下面的版本的程序:
count = 10
with open('/Users/abc/testfile.txt', 'r') as testfile:
for i, line in enumerate(testfile):
print line
if (i + 1) % count == 0:
if raw_input('Print More..') not in ['y', 'Y']:
break
这比原来的代码更短,而且也更有效(不需要阅读整个文件,然后建立一个巨大的列表),但这些不是很好的理由使用它。
一个很好的理由是它更健壮。这里有很少的显式循环逻辑可能导致错误。你甚至不需要记住切片是如何工作的(当然,很容易知道它们是[start:stop]
而不是[start:length]
......但是如果你使用另一种语言比Python更频繁地编程,而且你总是在编写s.sub(start, length)
,重新会忘记...)。当你到达文件末尾时,它也会自动结束,而不是一直持续下去,为你关闭文件(即使是在异常情况下,这很痛苦地手动取得),还有其他你还没有写的东西。
另一个很好的理由是它更容易阅读,因为尽可能地,代码告诉你它在做什么,而不是它如何做的细节。
但它仍然不完美,因为仍然有一件事你可能很容易出错:那(i + 1) % count == 0
位。事实上,我第一次尝试时出现了错误(我忘了+1,所以它在第0,10,20,......,而不是9,19,29 ......)后给了我一个“更多”提示。如果你有一个grouper
功能,你甚至可以更简单,鲁棒重写它:
with open('/Users/abc/testfile.txt', 'r') as testfile:
for group in grouper(testfile, 10):
for line in group:
print line
if raw_input('Print More..') not in ['y', 'Y']:
break
,或者甚至更好:
with open('/Users/abc/testfile.txt', 'r') as testfile:
for group in grouper(testfile, 10):
print '\n'.join(group)
if raw_input('Print More..') not in ['y', 'Y']:
break
不幸的是,有内置,说没有这样的石斑鱼功能,itertools
模块,但你可以写一个很容易:
def grouper(iterator, size):
return itertools.izip(*[iterator]*size)
(如效率问题,解决这个搜索网站,也有人们在-部门做了几个问题h比较不同的方式来达到同样的效果。但通常没关系。对于这个问题,如果你想了解为什么这个群组的东西,搜索这个网站,因为它已被解释至少两次。)
一个方面的注意事项:即使你解决这个问题,程序将永远循环一次你到达最后。如果文件长度为100行,则“行[100:110]”,“行[110:120]”等都是完全有效的空列表。你可能想'为了在f:'而不是写你自己的显式循环和计数器。另外,为什么导入你不需要的模块,为什么要分配'block'两次? – abarnert