如果有多个交叉点,有没有办法在嵌套列表中交换元素

2024-10-06 12:11:12 发布

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

我有一个嵌套列表,如下所示:

d4 = [[[a11, b11], [a12, b12]], 
      [a21, b21], [a22, b22]]]

这意味着代表2条同源染色体的4个姐妹染色单体上两个基因座(b为外基因座,a为内基因座)的等位基因。[a11,b11]是染色单体1上的两个等位基因(在a和b基因座上)。该染色单体有一个重复,但位于第二个染色单体[a12,b12]上。前两个染色单体构成第一条染色体。类似地,[[a21,b21],[a22,b22]]是两个姐妹染色单体(技术上为3,4),共同构成第2染色体。染色单体1对与染色单体3和2对与4进行重组

我们看待它的方式是,重组可以发生在第1对的b[[a11,b11],…,[a21,b21]]位点(我们称之为重组r1)。结果将是[[[a11,b21],[a12,b12],[a21,b11],[a22,b22]],本质上是b的交换。重组r2指的是同一事物,但在第2对的b之间[[a12,b12],…,[a22,b22])。重组r3指的是第一对的a之间的交换(但由于a基因座在染色体上较低,b基因座与其交换)。如果重组r3发生,结果可能是[[a21,b21],[a12,b12],[a11,b11],[a22,b22]]]相似性。对2[[a12,b12],…,[a22,b22]]也可能发生相似性,我们称之为重组。所有4个重组事件都可能发生或不发生(我们分配了0=不发生,1=发生)

我们使用该代码来确定4个重组事件发生与否的所有可能结果

events_b_list = []
for recomb_r1 in [0,1]:
    if (recomb_r1 == 0):
        p_1 = (1-r)
    else:
        p_1 = r
    for recomb_r2 in [0,1]:
        if (recomb_r2 == 0):
            p_2 = (1-r)
        else:
            p_2 = r
        for recomb_r3 in [0,1]:
            if (recomb_r3 == 0):
                p_3 = (1-r)
            else:
                p_3= r
            for recomb_r4 in [0,1]:
                if (recomb_r4 == 0):
                    p_4 = (1-r)
                else:
                    p_4= r
                events=[recomb_r1, recomb_r2, recomb_r3, recomb_r4]
                p = p_1 * p_2* p_3* p_4
                events_b_list.append([events,p])

结果是这样的,有相关的概率(不是很重要)

[[[0, 0, 0, 0], (1 - r)**4],
 [[0, 0, 0, 1], r*(1 - r)**3],
 [[0, 0, 1, 0], r*(1 - r)**3],
 [[0, 0, 1, 1], r**2*(1 - r)**2],
 [[0, 1, 0, 0], r*(1 - r)**3],
 [[0, 1, 0, 1], r**2*(1 - r)**2],
 [[0, 1, 1, 0], r**2*(1 - r)**2],
 [[0, 1, 1, 1], r**3*(1 - r)],
 [[1, 0, 0, 0], r*(1 - r)**3],
 [[1, 0, 0, 1], r**2*(1 - r)**2],
 [[1, 0, 1, 0], r**2*(1 - r)**2],
 [[1, 0, 1, 1], r**3*(1 - r)],
 [[1, 1, 0, 0], r**2*(1 - r)**2],
 [[1, 1, 0, 1], r**3*(1 - r)],
 [[1, 1, 1, 0], r**3*(1 - r)],
 [[1, 1, 1, 1], r**4]]

目标是让原始基因型遍历每个可能的事件,并生成一个包含所有交换等结果的列表


Tags: r3染色体r1b12a21b11b21a12
1条回答
网友
1楼 · 发布于 2024-10-06 12:11:12

首先,生成事件和概率的方法要短得多。可能的事件基本上都是二进制的4位数字,或者是长度为4的0和1的所有置换。因此,您可以执行for number in range(2**4)并提取每个数字的位以形成事件列表,或者只使用itertools.product()

for events in itertools.product([0, 1], repeat=4):
    ones = events.count(1)
    zeros = 4 - ones
    p = r**ones * (1 - r)**zeros

至于交换,您可以为每个recomb_rR执行d4[0][y][x], d4[1][y][x] = d4[1][y][x], d4[0][y][x],您只需要创建一个从每个R到适当的yx索引的映射。但是你要修改原始的d4,既然你想要所有的可能性,所以你无论如何都需要列表的单独副本,你最好从头开始创建交换的版本:只需创建一个新的版本,而不是例如a11你有d4[recomb_r3][0][0]-对于前4个项目,你将recomb_rR作为第一个索引,最后4个是补码,所以如果recomb_rR是0,对应的项将来自嵌套列表中的原始位置,但是如果是1,它们将被交换

当然,如果你可以自由地改变d4的格式和重组的顺序(即,哪个重组数意味着哪对,或者它们在events中的顺序),你可以通过使用d4 = [[a11, b11, a12, b12], [a21, b21, a22, b22]]并使重组顺序匹配events,使你的生活变得更加轻松;然后你就可以做result = [[d4[c^r][i] for i, r in enumerate(events)] for c in (0, 1)]

相关问题 更多 >