[英]is there a way to swap around elements in a nested list given there are multiple points of crossover- 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 ]] 基因座(我们称之为recomb_r1)。 结果将是 [[[a11, b21], [a12, b12], [a21, b11], [a22, b22]]],本质上是 b 的交换。 recomb_r2 指的是相同的东西,但在第 2 对的 b 之间 [[a12, b12 ],...,[a22, b22 ])。 recomb_r3 指的是第一对的 a 之间的交换(但由于 a 基因座在染色体上较低,因此 b 基因座与之交换)。 如果 recomb_r3 会发生 1 个结果可能是 [[[a21, b21], [a12, b12], [a11, b11], [a22, b22]]]。 对 2 [[a12, b12],...,[a22, b22]] 也可能发生相似性,我们称之为 recomb_r4。 所有 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]]
目标是通过每个可能的事件将原始基因型变为 go,并生成包含所有交换等的结果列表。
首先,有很多更短的方法来生成事件和概率。 可能的事件本质上是二进制的所有 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
至于交换,你可以做d4[0][y][x], d4[1][y][x] = d4[1][y][x], d4[0][y][x]
对于每个recomb_rR
,您只需要创建一个从每个R
到正确y
和x
索引的映射。 但是您将修改原始的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)]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.