比较两个文件时如何确保两个文件保持打开状态

时间:2014-06-09 06:35:11

标签: python file input intervals overlap

我有两个相当大的文件,每个文件都包含一个带有(开始,结束)信息的间隔列表。我必须输出第一个文件中的行,这些行包含与第二个文件中的行不重叠的间隔,因为某个字符串在两者之间是相同的。

以下是不重叠的区间的条件:

(start2 - end1) * (end2 - start1) < 0    TRUE

这是我的第一个测试文件(制表符分隔)。在此文件中,列[8]是(开始+ 1),可以通过将列[5]中指示的长度添加到起始值来计算结束。

TagO    XXXX    xxxx    46  a   36  +   chrX    131072906   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr5    24260   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr8    93179690    0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr1    228757224   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr1    228759444   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr1    228752768   0   36M 36
TagX    XXXX    xxxx    46  a   36  +   chr1    14355   0   36M 36
TagX    XXXX    xxxx    46  a   36  +   chr1    24260   0   36M 36
TagX    XXXX    xxxx    46  a   36  +   chr1    26320   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr1    228766167   0   36M 36

第二个测试文件(制表符分隔),表示不合需要的间隔的开始和结束:

chr1    14361   14408
chr1    16713   16749
chr1    18907   19048
chr1    19972   20405
chr1    20531   20679
chr1    21949   22075
chr1    23804   24038
chr1    24088   24250
chr1    24255   24448
chr1    26356   26412

输出应该看起来像这样(TagX与第二个文件中的间隔重叠,因此应该消失,但只有当file1中的列[7]和file2中的[0]包含相同的字符串时):

TagO    XXXX    xxxx    46  a   36  +   chrX    131072906   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr5    24260   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr8    93179690    0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr1    228757224   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr1    228759444   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr1    228752768   0   36M 36
TagO    XXXX    xxxx    46  a   36  +   chr1    228766167   0   36M 36

这是我的代码......

import sys

A = sys.argv[1]
B = sys.argv[2]

soap = open(A, 'r')
bed = open(B, 'r')

with soap as input1:
    for row1 in input1:
        chrom1 = row1.strip().split()[7]
        start1 = int(row1.strip().split()[8]) - 1
        end1 = start1 + int(row1.strip().split()[5])

        with bed as input2:
            for row2 in input2:
                chrom2 = row2.strip().split()[0]

                if chrom1 == chrom2:
                    start2 = int(row2.strip().split()[1])
                    end2 = int(row2.strip().split()[2])
                    test = (start2 - end1)*(end2 - start1)

                    if test < 0:
                        print row1.strip()

然后我在终端(Mac OS X)中使用以下命令运行它:

python remove.py file1.txt file2.txt > test_out.txt 

但是我收到以下错误消息:

Traceback (most recent call last):
  File "remove.py", line 16, in <module>
    with bed as input2:
ValueError: I/O operation on closed file

1 个答案:

答案 0 :(得分:1)

“bed”的with块在块完成后关闭文件。但通常你会在open语句中嵌入with函数调用,如下所示:

with open(B, 'r') as input2

而是您只打开文件一次,然后尝试在with循环内多次使用for进行操作。所以python抱怨文件对象只打开过一次,但是你试图重复使用它。

如果您希望每次通过for循环开始input2,那么您可以在open语句中嵌入with函数调用。

您也可以拒绝使用“with”语法(手动打开和关闭文件),或者您可以移动第二个“with”以包含for循环而不是将其放入其中,然后使用{{ 1}}返回循环内的开头。

如果文件很小,可能更有效的是在进入for循环之前将内容读入内存(例如列表),并仅在列表上进行迭代。