两个for循环,第二个仅在第一次迭代时执行 Python

1 投票
3 回答
2558 浏览
提问于 2025-04-17 15:01

我是一名Python新手,正在尝试比较两个文件中的行值,并输出“行名”,如果该行在第二个文件中,就输出1,如果缺失则输出0。第一次循环返回1,因为那一行在第二个文件中,但接下来的超过1000行都返回0,无论它们是否在第二个列表中。看起来第二个“for循环”只在第一次循环时执行。你们觉得这是为什么呢?这是我的代码:

    import sys  

    file1 = sys.argv[1] 

    file2 = sys.argv[2]

    name = str(file2)

    f1 = open(file1, 'r') 
    f2 = open(file1, 'r')
    o1 = open((name + '1.txt'), 'w')

    for line in f1:
        name = line.strip('\r\n')
        count = 0
        for line1 in f2:
            if name == line1.strip('\r\n'):
                count += 1
                print (str(name) + '\t' + str(1))
                o1.write(str(name) + '\t' + str(1) + '\r\n')
        if count == 0:
            print (str(name) + '\t' + str(0))
            o1.write(str(name) + '\t' + str(0) + '\r\n')

    f1.close()
    f2.close()
    o1.close()
Any help is very much appreciated!

经过一些修改,这就是我现在的代码,但它只返回'1'

f1 = open(file1, 'r') #opens files for reading
f2 = open(file2, 'r')
o1 = open((name + '1.txt'), 'w')

f2s = {line.strip('\n') for line in f2}

for line in f1:
    line = line.strip('\n')
    count = 0
    if line in f2s:
        count += 1
        print (str(line) + '\t' + str(1))
        o1.write(str(line) + '\t' + str(1) + '\n')
    if count == 0:
        print (str(line) + '\t' + str(0))
        o1.write(str(line) + '\t' + str(0) + '\n')

真尴尬,我竟然打开了同一个文件两次。真是个菜鸟。

3 个回答

0

标准库中的 difflib 可以帮助你比较文本行,也许你可以利用这个工具。

1

第一次执行 for line in f2: 时,它会把 f2 中的每一行都读一遍,这样文件指针就会停在文件的最后面。所以第二次再执行的时候,它就从文件的末尾开始,结果就没有剩下的行可以读了……

如果你想重复读取这些行,有几种方法可以做到。你可以把 f2 = open(file1, 'r') 放到外层循环里。或者你可以用 f2.seek(0, 0) 来重置文件指针。还有一种方法是使用 itertools.tee

不过,除非你的内存真的不够用来一次性存下整个文件,否则你可能更想在第一次读取时把这些行存到一个 list 里,然后就可以直接遍历这个 list 了:

l2 = list(f2)
# ...
for line in f1:
    # ...
    for line1 in l2:
        # ...
3

f2 是你第二个文件的一个迭代器,当这个文件被读取完后,它就用完了。

你可以通过 f2.seek(0, 0) 来重置这个迭代器,但这并不是最好的办法。

更好的做法是把 f2 中的所有值放到一个 set 里,然后只遍历一次 f1

f2s = {line.strip('\n') for line in f2}

for line in f1:
    name = line.strip('\n') # No need for \r\n
    if name in f2s:
        # etc.

如果你需要统计 f1 中每一行在 f2 中出现的次数,可以使用一个叫 Counter 的工具:

from collections import Counter
f2c = Counter(line.strip('\n') for line in f2)

for line in f1:
    name = line.strip('\n')
    if name in f2c:
        count = f2c[name]

撰写回答