【问题标题】:Finding regular expression with at least one repetition of each letter查找每个字母至少重复一次的正则表达式
【发布时间】:2023-03-10 09:48:01
【问题描述】:

从任何 *.fasta DNA 序列(仅“ACTG”字符)中,我必须找到每个字母至少重复一次的所有序列。

例如,从序列“AAGTCCTAG”中,我应该能够找到:“AAGTC”、“AGTC”、“GTCCTA”、“TCCTAG”、“CCTAG”和“CTAG”(每个字母的迭代)。

我不知道如何在 pyhton 2.7 中做到这一点。我正在尝试使用正则表达式,但它并未搜索所有变体。

我怎样才能做到这一点?

【问题讨论】:

  • 嗨!您能否包括您尝试失败的代码,并重新格式化您的问题以更明确地说明输入、预期输出和方法?这将使我们更容易提供帮助:)
  • 正则表达式可能不是这里的方式。
  • re.findall(r'(A+?C+?T+?G+?)',seqs) 输入是this 我必须在 DNA 序列中搜索“单词”,并且每个单词中必须至少包含一个 A、C、T ang G。当所有这些字母都在其中时,单词“结束”。我知道的就这些
  • 即使你使用正则表达式,你也需要重叠。

标签: python regex repeat dna-sequence


【解决方案1】:

您可以找到长度为 4+ 的所有子字符串,然后从这些子字符串中向下选择以仅找到包含每个字母之一的最短可能组合:

s = 'AAGTCCTAG'

def get_shortest(s):
  l, b = len(s), set('ATCG')
  options = [s[i:j+1] for i in range(l) for j in range(i,l) if (j+1)-i > 3]
  return [i for i in options if len(set(i) & b) == 4 and (set(i) != set(i[:-1]))]

print(get_shortest(s))

输出:

['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']

【讨论】:

    【解决方案2】:

    这是另一种方法。也许不如 chrisz answere 快和好。但是对于初学者来说可能更容易阅读和理解。

    DNA='AAGTCCTAG'
    toSave=[]
    for i in range(len(DNA)):
        letters=['A','G','T','C']
        j=i
        seq=[]
        while len(letters)>0 and j<(len(DNA)):
            seq.append(DNA[j])
            try:
                letters.remove(DNA[j])
            except:
                pass
            j+=1
        if len(letters)==0:
            toSave.append(seq)
    
    print(toSave)
    

    【讨论】:

      【解决方案3】:

      由于您要查找的子字符串可能是任意长度,因此 LIFO 队列似乎可以工作。一次附加每个字母,检查每个字母是否至少有一个。如果找到归还。然后去掉前面的字母,一直检查直到不再有效。

      def find_agtc_seq(seq_in):
          chars = 'AGTC'
          cur_str = []
          for ch in seq_in:
              cur_str.append(ch)
              while all(map(cur_str.count,chars)):
                  yield("".join(cur_str))
                  cur_str.pop(0)
      
      seq = 'AAGTCCTAG'
      for substr in find_agtc_seq(seq):
          print(substr)
      

      这似乎导致了您正在寻找的子字符串:

      AAGTC
      AGTC
      GTCCTA
      TCCTAG
      CCTAG
      CTAG
      

      【讨论】:

        【解决方案4】:

        我真的很想为此创建一个简短的答案,所以这就是我想出的!

        See code in use here

        s = 'AAGTCCTAG'
        d = 'ACGT'
        c = len(d)
        
        while c <= len(s):
            x,c = s[:c],c+1
            if all(l in x for l in d):
                print(x)
                s,c = s[1:],len(d)
        

        它的工作原理如下:

        • c 设置为我们确保字符串中存在的字符串长度 (d = ACGT)
        • while 循环遍历s 的每个可能的子字符串,使得c 小于s 的长度。
          • 这通过在 while 循环的每次迭代中将 c 增加 1 来实现。
          • 如果我们的字符串d (ACGT) 中的每个字符都存在于子字符串中,我们打印结果,将c 重置为其默认值,然后从开始将字符串分割为1 个字符。
          • 循环继续直到字符串sd

        结果:

        AAGTC
        AGTC
        GTCCTA
        TCCTAG
        CCTAG
        CTAG
        

        改为在列表中获取输出 (see code in use here):

        s = 'AAGTCCTAG'
        d = 'ACGT'
        c,r = len(d),[]
        
        while c <= len(s):
            x,c = s[:c],c+1
            if all(l in x for l in d):
                r.append(x)
                s,c = s[1:],len(d)
        
        print(r)
        

        结果:

        ['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']
        

        【讨论】:

          【解决方案5】:

          如果您可以将序列分解为列表,例如5 个字母的序列,然后您可以使用此功能查找重复的序列。

          from itertools import groupby
          import numpy as np
          
          def find_repeats(input_list, n_repeats):
              flagged_items = []
          
              for item in input_list:
                  # Create itertools.groupby object
                  groups = groupby(str(item))
          
                  # Create list of tuples: (digit, number of repeats)
                  result = [(label, sum(1 for _ in group)) for label, group in groups]
          
                  # Extract just number of repeats
                  char_lens = np.array([x[1] for x in result])   
          
                  # Append to flagged items
                  if any(char_lens >= n_repeats):
                      flagged_items.append(item)
          
              # Return flagged items
              return flagged_items
          
          #--------------------------------------
          test_list = ['aatcg', 'ctagg', 'catcg']
          
          find_repeats(test_list, n_repeats=2)  # Returns ['aatcg', 'ctagg']
          

          【讨论】:

          • 嗯,在我的笔记本电脑上运行时它是正确的。你能分享你的输出吗?
          • ctagg 违反了 OP 的要求。
          • 啊,我明白了。我误解了OP的问题。谢谢你的收获。此函数将仅返回列表中具有任何重复字符的项目;它不会以 OP 寻找的方式破坏字符串。
          猜你喜欢
          • 2020-08-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-05
          • 1970-01-01
          • 2021-02-19
          • 2013-06-24
          相关资源
          最近更新 更多