在两个词典中查找公共ID(交集)

时间:2014-04-30 10:28:19

标签: python dictionary bioinformatics

我写了一段代码,该代码应该在两个不同的文件中找到行[1]中常见的交叉ID。在我的小样本文件上它工作正常,但在我的大文件上没有。我无法弄清楚为什么,你能告诉我什么是错的吗?确切的问题是当我的输入是200时它给了我90个交叉点,如果我将它减少到150,它给我110的交叉点,逻辑上它不能更高。

fileA = open("file1.txt",'r')
fileB = open("file2.txt",'r')
output = open("result.txt",'w')
#fileA.next()

dictA = dict()
for line1 in fileA:
    listA = line1.split('\t')
    dictA[listA[1]] = listA

dictB = dict()
for line1 in fileB:
    listB = line1.split('\t')
    dictB[listB[1]] = listB

for key in set(dictA).intersection(dictB):
    output.write(dictB[key][0]+'\t'+dictA[key][1]+'\t'+dictA[key][4]+'\t'+dictA[key][5]+'\t'+dictA[key][9]+'\t'+dictA[key][10]+'\n')

我的file1按行[0]排序并有0-15行,为了简化这里我举一个例子只放行[0]和行[1],

contig17    GRMZM2G052619_P03  x x x x x x x x x x x x x x
contig33    AT2G41790.1    x x x x x x x x x x x x x x
contig98    GRMZM5G888620_P01  x x x x x x x x x x x x x x  
contig102   GRMZM5G886789_P02  x x x x x x x x x x x x x x  
contig123   AT3G57470.1    x x x x x x x x x x x x x x

我的文件2没有排序,有0-10行,我只给出行[1]

y GRMZM2G052619_P03 y y y y y y y y         
y GRMZM5G888620_P01 y y y y y y y y     
y GRMZM5G886789_P02 y y y y y y y y     

我想要的输出,

contig17    GRMZM2G052619_P03  y y y y
contig98    GRMZM5G888620_P01  y y y y  
contig102   GRMZM5G886789_P02  y y y y  

2 个答案:

答案 0 :(得分:1)

你应该缩小你的问题并在测试上发挥一点作用。我不会详细介绍如何使用测试框架并向您展示如何使用assert

assert有两个参数,第一个是表达式,预计是真的。 第二个是可选的,应包含对预期的真实假设。

以下是这些测试的修改示例:

fileA_txt = """contig17    GRMZM2G052619_P03  x x x x x x x x x x x x x x
contig33    AT2G41790.1    x x x x x x x x x x x x x x
contig98    GRMZM5G888620_P01  x x x x x x x x x x x x x x  
contig102   GRMZM5G886789_P02  x x x x x x x x x x x x x x  
contig123   AT3G57470.1    x x x x x x x x x x x x x x
"""
# or read it from file
#with open("filaA.txt") as f:
#  fileA_txt = f.read()
fileB_txt = """y GRMZM2G052619_P03 y y y y y y y y         
y GRMZM5G888620_P01 y y y y y y y y     
y GRMZM5G886789_P02 y y y y y y y y     
"""
# or read it from file
#with open("filaB.txt") as f:
#  fileB_txt = f.read()

dictA = dict()
for line1 in fileA_txt.splitlines():
    listA = line1.split()
    dictA[listA[1]] = listA
assert len(dictA) == 5, "fileA_txt shall contain 5 unique IDs"

dictB = dict()
for line1 in fileB_txt.splitlines():
    listB = line1.split()
    dictB[listB[1]] = listB
assert len(dictB) == 3, "fileA_txt shall contain 3 unique IDs"

common_IDs = set(dictA).intersection(dictB)
assert len(common_IDs) == 3, "there shall be just 3 common keys"

您应该使用您的文件并缩小正在运行和不运行的内容。

只需将fileA_txt(或替代方案,从文件中读取)替换为其他文件,这在以前是令人惊讶的。

添加更多断言,如果您发现了您可能期望的假设(例如,如果您的文件始终具有相同数量的行和唯一ID,请对其进行测试,则必须修改代码)

继续运行脚本,直到出现断言异常。

答案 1 :(得分:1)

请注意:

output.write(dictB[key][0]+'\t'+dictA[key][1]

这意味着您打印file2第一列而不是file1第二列。它与您的示例和所需输出不符。

至于交叉例程,它看起来非常正确,所以可能是你的文件出了问题。你确定所有的钥匙都是独特的吗?你是什​​么意思“减少到150” - 你的意思是从这个文件中删除一些行。

还可以更好地替换

for key in set(dictA).intersection(dictB):

for key in dictA:
   if key in dictB:

它实际上是相同的,但应该更快并且花费更少的内存。