嵌套循环中迭代变量值丢失

-1 投票
2 回答
706 浏览
提问于 2025-04-18 05:42

我好像在做一些非常傻的事情,但就是搞不明白。我想写一个脚本,用来在一个文件里搜索另一个文件中定义的词汇。对我来说,这听起来很简单,但不知为什么,外层循环在内层循环时是空的。

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

撰写回答