嵌套循环以在Python中查找所有可能的组合

时间:2012-04-24 22:57:27

标签: python loops nested bioinformatics

大家好我有生物信息学问题,我可以帮忙。它很长,但我会尝试将它分解成更小的部分,任何帮助都很棒。

我有一系列RNA长度' n'由4个字母A,U,C,G组成,它们作为字符串导入到Python中,可折叠形成循环。通过匹配序列中的字母对来制作循环,使得A与U,C与G,G与U,使得字符串自身折叠。

要抓住的是,必须有三个或更多的字母彼此相邻,形成一对,大于或等于3个字母,形成一对,并且至少3个部分之间必须有间隙信件也是如此。

我试图张贴一张照片,但我没有足够的声望点:(

在日记中,我引用作者讨论了一个嵌套循环方法,以找到可能的所有可能组合,然后将它们包含在一个组中,以便稍后调用。

我的问题是编写嵌套循环,因为我是编程和python的新手。除了以可以识别对并且可能将它们加在一起的方式存储序列。

再一次任何帮助都会很棒,如果有什么不清楚请告诉我

编辑:

一个例子是seq =' aggcuugaguuu'其中一个输出显示seq [0:2]与seq [9:11]的配对,这意味着代码形成了一个U形。

如果你把弦作为一个物理的弦线并将其保持在3个点并将其保持在三个不同的点然后一起触摸它们将导致弦形成一个循环。我正在寻找确定使用的6个点。

我没有找到为我编写的代码我只是想知道编写代码的方法。

我尝试了一种方法,其中seq1 =输入代码,seq2 =反向输入代码,并沿seq1移动seq2,寻找三个相邻的对,但这并没有给我正确的输出。

2 个答案:

答案 0 :(得分:4)

您是否考虑过使用itertools中的产品。然后你可以迭代结果,只选择你喜欢的结果。

答案 1 :(得分:3)

如果你的RNA不长(可能有数千个碱基可以正常;数十万个肯定不行),你可以使用简单的O(n ^ 3)算法。 O(n ^ 3)意味着执行时间在最坏的情况下与基数的立方成比例。提及嵌套循环的作者暗示了这种简单但相当慢的方法。

def find_loops(rna, min_pairs=3, min_loop=3):
    n = len(rna)
    result = []
    for loop_start in xrange(min_pairs, n - min_pairs - min_loop + 1):
        for loop_end in xrange(loop_start + min_loop, n - min_pairs):
            if (loop_end - loop_start < min_loop + 2 or 
                    not base_pair(rna[loop_start], rna[loop_end - 1])):
                max_pairs = min(loop_start, n - loop_end)
                for k in xrange(max_pairs):
                    if not base_pair(rna[loop_start - k - 1], rna[loop_end + k]):
                        break
                else:
                    k = max_pairs
                if k >= min_pairs:
                    result.append((loop_start - k, k, loop_end - loop_start))
    return result

def base_pair(x, y):
    return (x == 'A' and y == 'U' or
            x == 'C' and y == 'G' or
            x == 'G' and y == 'C' or
            x == 'U' and y == 'A')

这会迭代RNA环路的所有可能的开始和结束,然后在两个方向上离开潜在环的末端,只要碱基仍然配对。当它到达一对不匹配的基数时,它会停止并检查它是否至少具有最小数量的对。如果有,则将循环添加到结果列表中。

第一个if是为了避免列出可以“压缩”甚至更紧的循环。当条件读取时,如果循环太短(少于五个碱基)或其末端不匹配,则循环可以拉紧。

结果是一个元组列表,每个可能的循环一个,形式为(start_pos, pair_count, loop_length)。这意味着从基数pair_count开始的start_pos碱基序列之后是loop_length个碱基的环,然后是反向的互补序列。序列的反义拷贝从基础start_pos + pair_count + loop_length开始。第一个基数是0,而不是1(我们这里是程序员)。

一个例子可能会更清楚:print find_loops('GGGGAUUACAGCGUGUAAUCAAUA')返回[(4, 3, 13), (3, 7, 3)],也就是说,它找到两个循环:

  • 在第4位,三个基地AUU包围一个13个碱基的环,并绑定到位置20的AAU;
  • 在第3位,七个基地GAUUACA包围一个三个基地的环,并绑定到位置13的UGUAAUC

如果没有第一个if,函数也会返回类似于(3,6,5)的循环(即位置3处的GAUUAC包含一个包含五个碱基的循环并绑定到{{1}在位置14),与上面的(3,7,3)相同的循环,只是没有像它那样紧密地拉链。

希望这会有所帮助。如果您需要更快的算法,我确信有一个动态编程解决方案可以使用更长的字符串。让我知道,我会考虑一下。虽然不会那么容易理解......