python - 使用列表元素进行正则表达式搜索以在大型文档中查找匹配项

标签 python regex list

这是我的第一个脚本,我正在尝试比较两个基因组文件,其中一个比另一个具有更多的数据点。

文件的内容如下所示:

rs3094315       1       742429  AA
rs12562034      1       758311  GG
rs3934834       1       995669  CC

每个字段之间都有制表符。每个文件大约有 500,000 行。

为了轻松比较它们,我只想保留两个文件所包含的数据点,并丢弃它们中任何一个所独有的任何数据点。为此,我创建了所有唯一 DNA 位置的列表,现在我尝试搜索原始数据文件的每一行,并将不包含这些唯一 DNA 位置的所有行打印到新文件中。

我的代码中的所有内容都已正常运行,直到我尝试使用正则表达式搜索基因组文件以打印所有非唯一的 DNA 位置。我可以让脚本打印 for 循环内 LaurelSNP_left 列表中的所有项目,但是当我尝试对每个项目使用 re.match 时项目,我收到此错误消息:

Traceback (most recent call last):
  File "/Users/laurelhochstetler/scripts/identify_SNPs.py", line 57, in <module>
    if re.match(item,"(.*)", Line):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 137, in match
    return _compile(pattern, flags).match(string)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 242, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sre_compile.py", line 500, in compile
    p = sre_parse.parse(p, flags)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sre_parse.py", line 673, in parse
    p = _parse_sub(source, pattern, 0)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sre_parse.py", line 308, in _parse_sub
    itemsappend(_parse(source, state))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/sre_parse.py", line 401, in _parse
    if state.flags & SRE_FLAG_VERBOSE:
TypeError: unsupported operand type(s) for &: 'str' and 'int'

我的问题有两个:

  1. 如何在正则表达式中使用我的列表?
  2. 有更好的方法来完成我在这里想做的事情吗?

这是我的代码:

#!/usr/bin/env python
import re #this imports regular expression module
import collections

MomGenome=open('/Users/laurelhochstetler/Documents/genetics fun/genome_Mary_Maloney_Full_20110514145353.txt', 'r')
LaurelGenome=open('/Users/laurelhochstetler/Documents/genetics fun/genome_Laurel_Hochstetler_Full_20100411230740.txt', 'r')
LineNumber = 0 
momSNP = []
LaurelSNP = []
f = open("mom_edit.txt","w")
for Line in MomGenome:
    if LineNumber > 0:
        Line=Line.strip('\n')
        ElementList=Line.split('\t')

        momSNP.append(ElementList[0])

        LineNumber = LineNumber + 1
MomGenome.close()
for Line in LaurelGenome:
    if LineNumber > 0:
        Line=Line.strip('\n')
        ElementList=Line.split('\t')

        LaurelSNP.append(ElementList[0])

        LineNumber = LineNumber + 1
momSNP_multiset = collections.Counter(momSNP)            
LaurelSNP_multiset = collections.Counter(LaurelSNP)
overlap = list((momSNP_multiset and LaurelSNP_multiset).elements())
momSNP_left = list((momSNP_multiset - LaurelSNP_multiset).elements())
LaurelSNP_left = list((LaurelSNP_multiset - momSNP_multiset).elements())
LaurelGenome=open('/Users/laurelhochstetler/Documents/genetics fun/genome_Laurel_Hochstetler_Full_20100411230740.txt', 'r')
i = 0
for Line in LaurelGenome:
    for item in LaurelSNP_left:
            if i < 1961:
                if re.match(item, Line):
                    pass

                else:
                    print Line

            i = i + 1
    LineNumber = LineNumber + 1

最佳答案

简短回答:我认为您不需要正则表达式来完成您想要做的事情。

长答案:让我们分析一下您的代码。

一开始有:

LineNumber = 0 
MomGenome = open('20110514145353.txt', 'r')
for Line in MomGenome:
    if LineNumber > 0:
        Line = Line.strip('\n')
        ElementList = Line.split('\t')

        momSNP.append(ElementList[0])

        LineNumber = LineNumber + 1

MomGenome.close()

它可以通过 with 进行改进声明,我猜你的行计数只是为了跳过某种标题,我将使用 next()为此:

with open('20110514145353.txt') as mom_genome:
    next(mom_genome)    # skipping the first line
    for line in mom_genome:
        elements = line.strip().split('\t')
        mom_SNP.append(elements[0])

如果您注意到我也尝试避免使用 CamelCase 名称作为变量,这样您就可以遵循一些样式指南。我还将 .strip('\n') 更改为 .strip() 查看官方 str.strip()看看这是否仍然符合您的要求。
上述操作也可以在您的其他文件上完成。

阅读文件后,会出现以下行:

overlap = list((momSNP_multiset and LaurelSNP_multiset).elements())

你确定这符合你的要求吗?
and 不应该是 & ,例如:

overlap = list((momSNP_multiset & LaurelSNP_multiset).elements())

让我们看一下这个例子:

>>> from collections import Counter
>>> a = Counter(a=4, b=2, c=0, d=-2)
>>> b = Counter(a=2, b=0, c=0)
>>> a
Counter({'a': 4, 'b': 2, 'c': 0, 'd': -2})
>>> b
Counter({'a': 2, 'c': 0, 'b': 0})
>>> a and b    # This will return b
Counter({'a': 2, 'c': 0, 'b': 0})
>>> c & d    # this will return the common elements
Counter({'a': 2})

a 和 b 它将返回 b,因为 bool(a) 被评估为 True,取 a看看official doc .

然后就是比赛了,这个还真不清楚。你这样做:

LaurelGenome = open('20100411230740.txt', 'r')
i = 0
for Line in LaurelGenome:
    for item in LaurelSNP_left:
        if i < 1961:
            if re.match(item, Line):
                pass
            else:
               print Line

        i = i + 1
    LineNumber = LineNumber + 1

正如我一开始所说的,我认为你根本不需要正则表达式。
我认为你正在尝试做类似的事情:

with open('20100411230740.txt') as laural_genome:
    for line in laureal_genome:
        i = 0
        for item in laurelSNP_left:
            if i > 1960:
                break

            if line.strip().split('\t')[0] == item:
                print line

            i += 1

在这个答案中我猜测了很多,所以请随时提供更多信息并告诉我哪里猜错了:)

关于python - 使用列表元素进行正则表达式搜索以在大型文档中查找匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9344633/

相关文章:

python - 环境变量未在 Linux 中使用 load_dotenv() 加载

python - feincms 应用程序内容不适用于 feincms_translatedpage_or_base

javascript - 删除javascript中的全 Angular 和半 Angular 字符

英国电话号码的正则表达式

MySQL 连接和正则表达式

python - 2D Python 列表将有随机结果

python - 带有 python 列表的循环引用

python - Numpy 广播数组

即时进行 Python 字符串格式化

c# - 如何从Unity3d和C#中的另一个脚本访问在单例类中创建的列表