提取子串模式

2024-10-03 04:26:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有1200个序列

>3fm8|A|A0JLQ2
CFLVNLNADPALNELLVYYLKEHTLIGSANSQDIQLCGMGILPEHCIIDITSEGQVMLTP
QKNTRTFVNGSSVSSPIQLHHGDRILWGNNHFFRLNLP


>2ht9|A|A0JLT0
LATAPVNQIQETISDNCVVIFSKTSCSYCTMAKKLFHDMNVNYKVVELDLLEYGNQFQDA
LYKMTGERTVPRIFVNGTFIGGATDTHRLHKEGKLLPLVHQCYL

我想读每个可能的模式,中间有半胱氨酸,开头有五个字符串,后面还有其他五个字符串,比如xxxxx cxxxxx

输出应如下所示:

  • QDIQLCGMGIL公司
  • Ilpehcidit公司
  • TISDNCVVIFS公司
  • FSKTSCSYCTM公司

这是图中只给出C的位置。这不是我想要的工作

pos=[]

def find(ch,string1):

    for i in range(len(string1)):
        if ch == string1[i]:
            pos.append(i)
            return pos



z=find('C','AWERQRTCWERTYCTAAAACTTCTTT')

print z

Tags: 字符串pos模式公司序列findchstring1
2条回答

我的解决方案基于regex,并显示了使用regex和while循环的所有可能的解决方案。感谢@Smac89通过将其转化为发电机对其进行改进:

import re

string = """CFLVNLNADPALNELLVYYLKEHTLIGSANSQDIQLCGMGILPEHCIIDITSEGQVMLTPQKNTRTFVNGSSVSSPIQLHHGDRILWGNNHFFRLNLP

LATAPVNQIQETISDNCVVIFSKTSCSYCTMAKKLFHDMNVNYKVVELDLLEYGNQFQDA LYKMTGERTVPRIFVNGTFIGGATDTHRLHKEGKLLPLVHQCYL"""

# Generator
def find_cysteine2(string):

    # Create a loop that will utilize regex multiple times
    # in order to capture matches within groups
    while True:
        # Find a match
        data = re.search(r'(\w{5}C\w{5})',string)

        # If match exists, let's collect the data
        if data:
            # Collect the string
            yield data.group(1)

            # Shrink the string to not include 
            # the previous result
            location = data.start() + 1
            string = string[location:]

        # If there are no matches, stop the loop
        else:
            break

print [x for x in find_cysteine2(string)]
# ['QDIQLCGMGIL', 'ILPEHCIIDIT', 'TISDNCVVIFS', 'FSKTSCSYCTM', 'TSCSYCTMAKK']

您需要在循环之外返回,因为您将在第一个匹配中返回,所以您的列表中只有一个字符:

def find(ch,string1):  
    pos = []
    for i in range(len(string1)):
        if ch == string1[i]:
            pos.append(i)
    return pos # outside

也可以使用enumerate和list comp来代替范围逻辑:

def indexes(ch, s1):  
    return [index for index, char in enumerate(s1)if char == ch and 5 >= index <= len(s1) - 6]

列表comp中的每个index是字符索引,每个char是实际字符,因此我们保留char等于ch的每个索引

如果你想要两面的五个字符:

In [24]: s="CFLVNLNADPALNELLVYYLKEHTLIGSANSQDIQLCGMGILPEHCIIDITSEGQVMLTP QKNTRTFVNGSSVSSPIQLHHGDRILWGNNHFFRLNLP"

In [25]: inds = indexes("C",s)

In [26]: [s[i-5:i+6] for i in inds]
Out[26]: ['QDIQLCGMGIL', 'ILPEHCIIDIT']

我添加了检查索引的功能,因为如果索引是<;5并且从末尾开始是相同的,那么显然我们无法在C之前获得5个字符。你知道吗

您可以在单个函数中完成这一切,在找到匹配项时生成一个切片:

def find(ch, s):
    ln = len(s)
    for i, char in enumerate(s):
        if ch == char and 5 <= i <= ln - 6:
            yield s[i- 5:i + 6]

假设问题中的数据实际上是yoru文件中的两行:

s="""">3fm8|A|A0JLQ2CFLVNLNADPALNELLVYYLKEHTLIGSANSQDIQLCGMGILPEHCIIDITSEGQVMLTPQKNTRTFVNGSSVSSPIQLHHGDRILWGNNHFFRLNLP
>2ht9|A|A0JLT0LATAPVNQIQETISDNCVVIFSKTSCSYCTMAKKLFHDMNVNYKVVELDLLEYGNQFQDALYKMTGERTVPRIFVNGTFIGGATDTHRLHKEGKLLPLVHQCY"""

跑步:

for line in s.splitlines():
    print(list(find("C" ,line)))

将输出:

['0JLQ2CFLVNL', 'QDIQLCGMGIL', 'ILPEHCIIDIT']
['TISDNCVVIFS', 'FSKTSCSYCTM', 'TSCSYCTMAKK']

它给出了六个匹配项,而不是你预期的四个匹配项,所以我猜你没有包括所有可能的匹配项。你知道吗

您还可以使用^{}加速代码,从最后一个匹配索引+1开始进行后续的每个匹配

def find(ch, s):
    ln, i = len(s) - 6, s.find(ch)
    while 5 <= i <= ln:
        yield s[i - 5:i + 6]
        i = s.find(ch, i + 1)

这将产生相同的输出。当然,如果字符串不能重叠,您可以开始寻找下一个匹配的字符串更进一步每次。你知道吗

相关问题 更多 >