在循环中查找并打印相同的元素

时间:2014-04-04 09:42:35

标签: python bioinformatics

我有一个巨大的输入文件,看起来像这样,

c651    OS05T0-00    492    749 29.07
c651    OS01T0-00    1141   1311    55.00
c1638   MLOC_8.3     27 101 72.00
c1638   MLOC_8.3     25 117 70.97
c2135   TRIUR3_3-P1  124    210 89.66
c2135   EMT17965    25  117 70.97
c1914   OS02T0-00    2  109 80.56
c1914   OS02T0-00    111    155 93.33
c1914   OS08T0-00    528    617 50.00

我想在每个c中迭代,看看它是否在第[1]行中有相同的元素并在2个单独的文件中打印

  1. c包含相同的元素和
  2. 没有相同的元素。
  3. 在c1914的情况下,因为它有2个相同的元素而1不是,所以它转到文件2.所以想要的2个输出文件看起来像这样,file1.txt

    c1638   MLOC_8.3     27 101 72.00
    c1638   MLOC_8.3     25 117 70.97
    

    FILE2.TXT

    c651    OS05T0-00    492    749 29.07
    c651    OS01T0-00    1141   1311    55.00
    c2135   TRIUR3_3-P1  124    210 89.66
    c1914   OS02T0-00    2  109 80.56
    c1914   OS02T0-00    111    155 93.33
    c1914   OS08T0-00    528    617 50.00
    

    这就是我试过的,

    oh1=open('result.txt','w')
    oh2=open('result2.txt','w')
    f=open('file.txt','r')
    lines=f.readlines()
    for line in lines:
        new_list=line.split()
        protein=new_list[1]
        for i in range(1,len(protein)):
            (p, c) = protein[i-1], protein[i]
            if c == p:
                new_list.append(protein)
                oh1.write(line)
            else:
                oh2.write(line)
    

2 个答案:

答案 0 :(得分:1)

试试这个......

import collections

parsed_data = collections.OrderedDict()

with open("input.txt", "r") as fd:
    for line in fd.readlines():
        line_data = line.split()
        key = line_data[0]
        key2 = line_data[1]
        if not parsed_data.has_key(key):
            parsed_data[key] = collections.OrderedDict()
        if not parsed_data[key].has_key(key2):
            parsed_data[key][key2] = [line]
        else:
            parsed_data[key][key2].append(line)

# now process the parsed data and write result files
fsimilar = open("similar.txt", "w")
fdifferent = open("different.txt", "w")

for key in parsed_data:
    if len(parsed_data[key]) == 1:
        f = fsimilar
    else:
        f = fdifferent
    for key2 in parsed_data[key]:
        for line in parsed_data[key][key2]:
            f.write(line)
fsimilar.close()
fdifferent.close()

希望这有帮助

答案 1 :(得分:1)

如果我理解正确,如果所有这些行的第二个元素txt1相同,则您希望将输入文件的所有行(第一个元素txt2)发送到第一个输出文件;否则所有这些行都转到第二个输出文件。这是一个程序。

from collections import defaultdict

# Read in file line-by-line for the first time
# Build up dictionary of txt1 to set of txt2 s
txt1totxt2 = defaultdict(set)
f=open('file.txt','r')
for line in f:
    lst = line.split()
    txt1=lst[0]
    txt2=lst[1]
    txt1totxt2[txt1].add(txt2);

# The dictionary tells us whether the second text
# is unique or not. If it's unique the set has
# just one element; otherwise the set has > 1 elts.
# Read in file for second time, sending each line
# to the appropriate output file
f.seek(0)
oh1=open('result1.txt','w')
oh2=open('result2.txt','w')

for line in f:
    lst = line.split()
    txt1=lst[0]
    if len(txt1totxt2[txt1]) == 1:
        oh1.write(line)
    else:
        oh2.write(line)

程序逻辑非常简单。对于每个txt,它会构建一个set txt2txt2。当您完成阅读文件后,如果该集只有一个元素,那么您就知道txt2是唯一的;如果集合有多个元素,那么至少有两个txt1 s。请注意,这意味着如果输入文件中只有一个行,并且具有特定的lines=f.readlines(),则它将始终发送到第一个输出文件。如果这不是你想要的行为,有很多方法。

另请注意,由于文件很大,我已逐行阅读:原始程序中的lines=f.readlines()一次将整个文件读入内存。我已经两次介入了它:第二次输出。如果这增加了运行时间,那么您可以恢复txt1totxt2而不是第二次读取它。但是,对于非常大的文件,程序应该更加健壮。相反,如果您的文件确实非常大,那么值得查看该程序以进一步减少内存使用(字典txt1totxt2可以用更优化的东西替换,尽管更复杂,如果有必要的话)。

编辑:关于此算法的内存成本的评论(现已删除)中有一个好点。详细说来,内存使用率可能很高,但另一方面它并不像存储整个文件那么严重:而{{1}}是从每行第一个文本到第二个文本集的字典。 ,(唯一的第一文本的大小)*(每个唯一的第一文本的唯一第二文本的平均大小)。这可能比文件大小小很多,但该方法可能需要进一步优化。这里的方法是首先获得简单的东西 - 然后可以迭代,以便在必要时进一步优化。