2016-04-13 33 views
2

我有很長的文件像1200個序列提取物串模式

>3fm8|A|A0JLQ2 
CFLVNLNADPALNELLVYYLKEHTLIGSANSQDIQLCGMGILPEHCIIDITSEGQVMLTP 
QKNTRTFVNGSSVSSPIQLHHGDRILWGNNHFFRLNLP 


>2ht9|A|A0JLT0 
LATAPVNQIQETISDNCVVIFSKTSCSYCTMAKKLFHDMNVNYKVVELDLLEYGNQFQDA 
LYKMTGERTVPRIFVNGTFIGGATDTHRLHKEGKLLPLVHQCYL 

我想讀的每一個可能的模式在中間的半胱氨酸,並在開始五絃和其他五個字符串遵循如xxxxxCxxxxx

輸出應該是這樣的:

  • QDIQLCGMGIL
  • ILPEHCIIDIT
  • TISDNCVVIFS
  • FSKTSCSYCTM

這是pogram只給出的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 
+0

實際上,我在這裏有用例需要指導。爲什麼不''TSCSYCTMAKK'而不是'FSKTSCSYCTM',或者這很重要? – Adib

+0

我認爲我通過識別所有案例解決了這個問題 – Adib

回答

2

工作,你需要返回循環外,你正在返回的第一場比賽,所以你永遠只能在你的清單得到一個單一的字符:

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

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

每個index列表中的補償:

您可以將您的範圍的邏輯也使用enumerate與列表比較是字符索引,並且每個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'] 

我加了檢查,因爲我們顯然不能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] 

凡在你的問題假設的數據實際上是從夜兩行的文件,如:

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

運行:

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

將輸出:

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

這給出了六個匹配不是四個作爲您的預期輸出建議,所以我認爲你沒有包括所有可能的匹配。

您也可以加快使用str.find代碼,開始最後一場比賽索引+ 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) 

這將給相同的輸出。當然如果這些字符串不能重疊,你可以開始在每一次字符串中進一步查找下一個匹配。

+0

我注意到他提供的輸出在某些情況下(如我評論的那樣)在中間跳過了「C」。我想知道這是故意的嗎? (特別是因爲你的解決方案顯示了多個案例) – Adib

+0

@Adib,我自己重讀這個問題,其中一些實際上並不加起來 –

+0

認爲你的幫助,但這隻會使每個C – samooo

1

我的解決方案基於正則表達式,並使用正則表達式和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'] 
+1

它也在工作。非常感謝你 – samooo

+0

爲了減少大輸入的內存開銷 – smac89

+0

@samooo Yup!它並不關心它是一條線,兩條線,1200條線,它會發現它很快:D – Adib