嵌套循环中迭代变量值丢失
我好像在做一些非常傻的事情,但就是搞不明白。我想写一个脚本,用来在一个文件里搜索另一个文件中定义的词汇。对我来说,这听起来很简单,但不知为什么,外层循环在内层循环时是空的。
if __name__ == "__main__":
searchfile = open(sys.argv[1],"r")
terms = open(sys.argv[2],"r")
for line in searchfile:
for term in terms:
if re.match(term, line.rstrip()):
print line
如果我在词汇循环之前打印这一行,它是有内容的。但如果我在词汇循环里面打印这一行,就没有内容了。我到底漏掉了什么呢?
2 个回答
1
那么你在做什么呢:在第一次循环中,你读取了searchfile
的第一行,并把它和terms
中的每一行进行比较,这个过程是通过读取terms
文件来完成的。之后,terms
文件就被完全读取完了,所以在接下来的每一次searchfile
的循环中,terms
的循环就不再执行了(因为terms
已经“空”了)。
2
这里的问题是,文件是一次性使用的迭代器——这意味着一旦你读取过一次文件,它就不能再从头开始读取了。
你可能习惯于列表——这些是每次循环时都会从头开始返回一个新迭代器的可迭代对象。
而文件是单次使用的可迭代对象——一旦你读取过它,它就被耗尽了。
你可以使用 list()
来构建一个可以多次读取的列表,或者在循环中每次都打开文件,这样每次都会重新打开文件,从头开始创建一个新的迭代器。
哪种选择更好取决于具体情况。打开文件并从磁盘读取会比较慢,但如果你创建一个列表,所有数据都会存储在内存中——如果你的文件非常大,这可能会成为一个问题。
另外,值得注意的是,在Python中打开文件时,应该使用 with
语句。
with open(sys.argv[1], "r") as searchfile, open(sys.argv[2], "r") as terms:
terms = list(terms)
for line in searchfile:
for term in terms:
if re.match(term, line.rstrip()):
print line