在python中写入文件而不使用冗余行

在python中写入文件而不使用冗余行,python,Python,我正在编写python脚本,从输入文件中读取一行,并将唯一的行(如果输出文件中还没有相同的行)写入输出文件。不知何故,我的脚本总是将输入文件的第一行附加到输出文件,即使输出文件中已经存在同一行。我不明白为什么会这样。 有人知道我为什么和如何解决这个问题吗? 谢谢 在附加模式下打开文件时,文件对象位置位于文件末尾。因此,第一次通过时,当fo:中的第2行到达时,fo中不再有任何行,因此跳过该块,标志仍然为真,因此第一行被写入输出文件。在此之后,您将执行fo.seek(0),因此您将对照整个文件检查后

我正在编写python脚本,从输入文件中读取一行,并将唯一的行(如果输出文件中还没有相同的行)写入输出文件。不知何故,我的脚本总是将输入文件的第一行附加到输出文件,即使输出文件中已经存在同一行。我不明白为什么会这样。 有人知道我为什么和如何解决这个问题吗? 谢谢


在附加模式下打开文件时,文件对象位置位于文件末尾。因此,第一次通过时,当fo:中的第2行到达
时,
fo
中不再有任何行,因此跳过该块,
标志
仍然为真,因此第一行被写入输出文件。在此之后,您将执行
fo.seek(0)
,因此您将对照整个文件检查后续行。

在附加模式下打开文件时,文件对象位置位于文件的末尾。因此,第一次通过时,当fo:
中的第2行到达
时,
fo
中不再有任何行,因此跳过该块,
标志
仍然为真,因此第一行被写入输出文件。之后,您将执行fo.seek(0)
,因此您将对照整个文件检查后续行。

您的标志从未设置为False

flag==True
是一个等式

flag=True
是一个赋值

试试后者

import  os

input_file= 'input.txt'
output_file = 'output.txt'

fo = open(output_file, 'a+')
flag = False
with open(input_file, 'r') as fi:
    for line1 in fi:
       #print line1
       for line2 in fo:
           #print line2
           if line2 == line1:
               flag = True
               print('Found Match!!')
               print (line1,line2)
               break
       if flag == False:
           fo.write(line1)
       elif flag == True:
           flag = False
       fo.seek(0)

你的旗帜从未设为假

flag==True
是一个等式

flag=True
是一个赋值

试试后者

import  os

input_file= 'input.txt'
output_file = 'output.txt'

fo = open(output_file, 'a+')
flag = False
with open(input_file, 'r') as fi:
    for line1 in fi:
       #print line1
       for line2 in fo:
           #print line2
           if line2 == line1:
               flag = True
               print('Found Match!!')
               print (line1,line2)
               break
       if flag == False:
           fo.write(line1)
       elif flag == True:
           flag = False
       fo.seek(0)
by正确地解释了代码不工作的原因;您需要使用模式
'r+'
而不是
'a+'
,或者将
fo.seek(0)
放在
循环的开头而不是结尾

也就是说,有一种比读取输入文件每一行的整个输出文件更好的方法

def ensure_file_ends_with_newline(handle):
    position = handle.tell()

    handle.seek(-1, 2)
    handle_end = handle.read(1)
    if handle_end != '\n':
        handle.write('\n')

    handle.seek(position)


input_filepath = 'input.txt'
output_filepath = 'output.txt'

with open(input_file, 'r') as infile, open(output_file, 'r+') as outfile:
    ensure_file_ends_with_newline(outfile)

    written = set(outfile)

    for line in infile:
        if line not in written:
            outfile.write(line)
            written.add(line)
by正确地解释了代码不工作的原因;您需要使用模式
'r+'
而不是
'a+'
,或者将
fo.seek(0)
放在
循环的开头而不是结尾

也就是说,有一种比读取输入文件每一行的整个输出文件更好的方法

def ensure_file_ends_with_newline(handle):
    position = handle.tell()

    handle.seek(-1, 2)
    handle_end = handle.read(1)
    if handle_end != '\n':
        handle.write('\n')

    handle.seek(position)


input_filepath = 'input.txt'
output_filepath = 'output.txt'

with open(input_file, 'r') as infile, open(output_file, 'r+') as outfile:
    ensure_file_ends_with_newline(outfile)

    written = set(outfile)

    for line in infile:
        if line not in written:
            outfile.write(line)
            written.add(line)


您正在以附加模式打开它。你认为是因为这个吗?另外,当您与一起使用时,不需要显式关闭。因此,为了清楚起见,您希望仅当输出文件中不存在行时,才将行从输入文件写入输出文件;正确的?如果一行在输出文件中没有出现,但在输入文件中出现了不止一次,该怎么办?我的输入文件已经由唯一的行组成,但输出文件没有被多个输入文件更新。这些文件有多大?您正在以追加模式打开它。你认为是因为这个吗?另外,当您与一起使用时,不需要显式关闭。因此,为了清楚起见,您希望仅当输出文件中不存在行时,才将行从输入文件写入输出文件;正确的?如果一行没有出现在输出文件中,但它在输入文件中出现了不止一次呢?我的输入文件已经由唯一的行组成,但输出文件没有被多个输入文件更新。这些文件有多大?这并不能解决他问到的问题,但它确实解决了我注意到的另一个问题,第一次匹配后没有任何行写入输出文件。我一定误解了他的问题。运行代码,只注意到第二个bug。接得好,谢谢你接这个。我也做了一个更改。这并没有解决他问的问题,但它确实解决了我注意到的另一个问题,即第一次匹配后没有任何行写入输出文件。我一定误解了他的问题。运行代码,只注意到第二个bug。接得好,谢谢你接这个。我也做了一个改变。如果文件可能很大,那么在内存中保存全部内容将是一个问题。也就是说,如果你知道你有小文件要处理,这会更好。另外,我还没有意识到在一个
语句中可以有多个文件对象,所以我很高兴了解到这一点!谢谢。@Kmachinis,我考虑过了,但是如果你的文件那么大,那么在输入文件中每一行读取一次整个文件的IO成本是巨大的。如果您处理的文件太大,无法放入内存,有比执行所有IO更好的方法。如果文件太大,则将整个内容保存在内存中将是一个问题。也就是说,如果你知道你有小文件要处理,这会更好。另外,我还没有意识到在一个
语句中可以有多个文件对象,所以我很高兴了解到这一点!谢谢。@Kmachinis,我考虑过了,但是如果你的文件那么大,那么在输入文件中每一行读取一次整个文件的IO成本是巨大的。如果您处理的文件太大,无法放入内存,有比执行所有IO更好的方法。我不知道“a”pend选项会将指针移动到文件末尾,这就是为什么它不比较第一行的原因。按照您的建议,在for循环之前移动fo.seek(0)修复了我的问题。我不知道“a”pend选项将指针移动到文件末尾,这就是为什么它不比较第一行的原因。按照您的建议,在for循环之前移动fo.seek(0)修复了我的问题。