【问题标题】:Searching a file with the contents of another file python使用另一个文件python的内容搜索文件
【发布时间】:2013-02-03 10:29:36
【问题描述】:

我有一个文件,每行都有一个唯一的 ID 号。我正在尝试在不同的文件中搜索这些 ID 号的出现,并将这些 ID 号在第二个文件中的行返回,在本例中为输出文件。我是编程新手,这就是我目前所拥有的。

outlist = []
with open('readID.txt', 'r') as readID, \
     open('GOlines.txt', 'w') as output, \
     open('GO.txt', 'r') as GO:  
     x = readID.readlines()
     print x
     for line in GO:
        if x[1:-1] in line:
        outlist.append(line)
        outlist.append('\n')

     if x[1:-1] in line:
        outlist.append(line)
        outlist.append('\n')
     print outlist
     output.writelines(outlist)

文件如下所示:readID.txt

00073810.1
00082422.1
00018647.1
00063072.1

GO.txt

#query  GO  reference DB    reference family    
HumanDistalGut_READ_00048904.2  GO:0006412  TIGRFAM TIGR00001    
HumanDistalGut_READ_00043244.3  GO:0022625  TIGRFAM TIGR00001    
HumanDistalGut_READ_00048644.4  GO:0000315  TIGRFAM TIGR00001   
HumanDistalGut_READ_00067264.5  GO:0003735  TIGRFAM TIGR00001

读取的 id 与 READ...

之后的一些但不是全部的 id 匹配

【问题讨论】:

  • 修复属性错误而不是使用 readlines() 做 x=readID.read().splitlines()
  • x 是一个list 行,而不仅仅是一个行。所以,你必须对x = [line.strip('\n') for line in x] 到strip 进行所有操作。但是,正如@SuperFamousGuy 所建议的那样,首先阅读它们而不使用换行符会更容易。
  • 感谢您的帮助。我还注意到它应该用于 x[] 而不是 GO,它适用于 x 列表的离散值,但它不喜欢 x[1:-1]。 TypeError: 'in ' 需要字符串作为左操作数,而不是列表
  • 您要匹配 00073810.1 还是 00073810?它应该在 GO.txt 中匹配到哪里? READ_[ID].2、READ_[ID] 还是 GO:[ID]?你现在能明白用这么多缺失的细节来回答你的问题是多么困难吗? :p
  • 我再次道歉。包括小数在内的完整数字应与 READ_[ID] 匹配。我正在挖掘 GO:# 在输出文件中包含整行之后我可以隔离它。再次感谢您帮助我,我很迷茫......

标签: python file list search strip


【解决方案1】:
#!/usr/bin/env python
# encoding: utf-8

import sys
import re

def extract_id(line):
    """
    input: HumanDistalGut_READ_00048904.2  GO:0006412  TIGRFAM TIGR00001
    returns: 00048904.2
    """
    result = re.search(r'READ_(\d{8}\.\d)', line)
    if result != None:
        return result.group(1)
    else:
        return None

def extract_go_num(line):
    """
    input: HumanDistalGut_READ_00048904.2  GO:0006412  TIGRFAM TIGR00001
    returns: 0006412
    """
    result = re.search(r'GO:(\d{7})', line)
    if result != None:
        return result.group(1)
    else:
        return None

def main(argv = None):
    if argv is None:
        argv = sys.argv

    with open('readID.txt', 'r') as f:
        ids = frozenset(f.readlines())

    with open('GO.txt', 'r') as haystack, \
        open('GOLines.txt', 'w') as output:

        for line in haystack:
            if extract_id(line) in ids:
                output.write(extract_go_num(line) + '\n')

if __name__ == "__main__":
    sys.exit(main())

我将内存开销换成 O(n) 解决方案,而不是 O(n^2)。

我正在使用正则表达式来提取ids和go numbers,但是如果位数改变它会很脆弱。

【讨论】:

  • 我在比较 id 时忘了去掉换行符。
  • 它适用于我的测试输入。在某个时刻,我们所能做的就是提供可能的解决方案/总体思路;我们不能为您做所有事情。试着理解为什么某事有效或无效。如果您不理解某些内容,请将其分解为更小的部分并自己进行测试或提问。像“它仍然是空的”这样的通用回答对你我都没有帮助。
  • 我很抱歉你是对的。我不确定为什么它对我不起作用,我会尝试更多地弄乱它。
  • 非常感谢威廉!这似乎确实有效,并且不用担心格式非常严格的脆性。我会再做一些检查以确保它看起来不错。你介意解释一下它看起来像一个复杂的脚本吗?再次感谢您的宝贵时间。
  • 您对哪些部分有疑问?
【解决方案2】:

可能是这样的:

with open('readID.txt', 'r') as readID, open('GOlines.txt', 'w') as output, open('GO.txt', 'r') as GO:
    for ID in readID:
        for line in GO:
            if ID in line:
                output.write(line)

【讨论】:

  • 嗯,你能从 GO.txt 中发布一些输入 ID 和一些数据吗?
【解决方案3】:

如果您的文件足够小以适合您的内存。

with open('/somepath/GO.txt') as f:
    pool = f.readlines()

with open('/somepath/readID.txt') as f:    
    tokens = f.readlines()

# strip spaces/new lines
tokens = [t.strip() for t in tokens]
found = [(t, lno) for t in tokens for (lno, l) in enumerate(pool) if t in l]

然后您可以将您的found 列表打印到您的输出文件中。

【讨论】:

  • 我喜欢这个,但我认为文件太大,GO 文件是 80Mb。当我运行这个脚本时,它似乎只是冻结了终端。
猜你喜欢
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 2013-11-24
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
相关资源
最近更新 更多