通过列表列表排序以查找共享变体
sorting through lists of lists to find shared variants
我有一个名为 allLinesList
的列表列表,allLinesList
的每一行包含四个列表。这是 allLinesList
中的两行
[[['ACmerged_contig_10464', '668', '.', 'A', 'G', '3.87133', '.', 'DP=1;SGB=-0.379885;MQ0F=0;AC=0;AN=2;DP4=0,0,0,1;MQ=28', 'GT:PL', '0/0:28,3,0'], ['ACmerged_contig_10464', '668', '.', 'A', 'G', '3.87133', '.', 'DP=1;SGB=-0.379885;MQ0F=0;AC=0;AN=2;DP4=0,0,0,1;MQ=28', 'GT:PL', '0/0:28,3,0'], ['ACmerged_contig_10464', '747', '.', 'T', '.', '84', '.', 'DP=2;MQ0F=0;AN=2;DP4=0,2,0,0;MQ=32', 'GT', '0/0'], ['ACmerged_contig_10464', '747', '.', 'T', '.', '84', '.', 'DP=2;MQ0F=0;AN=2;DP4=0,2,0,0;MQ=32', 'GT', '0/0']],
[['ACmerged_contig_10464', '4', '.', 'T', '.', '29.5864', '.', 'DP=1;MQ0F=0;AN=0;DP4=0,0,0,0;MQ=.', 'GT', './.'], ['ACmerged_contig_10464', '4', '.', 'T', '.', '29.5864', '.', 'DP=1;MQ0F=0;AN=0;DP4=0,0,0,0;MQ=.', 'GT', './.'], ['ACmerged_contig_10464', '4', '.', 'T', '.', '29.5864', '.', 'DP=1;MQ0F=0;AN=0;DP4=0,0,0,0;MQ=.', 'GT', './.'], ['ACmerged_contig_10464', '4', '.', 'T', '.', '29.5864', '.', 'DP=1;MQ0F=0;AN=0;DP4=0,0,0,0;MQ=.', 'GT', './.']]]
allLinesList
总共有几千行。
我想遍历 allLinesList
中的所有这些行,并挑出特定内部列表与其第 5 项共享相同字符的行,只要该字符不是 '.'
.一旦我确定了这样的行,我就会将该行的第一项放入单独的列表中。
例如,在上面的第一个列表中,前两个内部列表共享 'G'
作为它们的第 5 个项目。因此,我想将这些列表之一输出到另一个列表。这将创建另一个列表列表,但只有两层列表,而不是像我的示例那样的三层列表。
我有可以执行此操作的代码,但我认为必须有更有效的方法来执行此操作,也许是使用循环,但我还没有弄清楚。这是我当前的代码:
sharedLists1_2 = []
i = 0
while i < len(allLinesList):
if allLinesList[i][0][4] != "." and allLinesList[i][0][4] == allLinesList[i][1][4] and allLinesList[i][1][4] != allLinesList[i][2][4] and allLinesList[i][1][4] != allLinesList[i][3][4]:
sharedLists1_2.append(allLinesList[i][1])
i +=1
目前,我运行这个代码的版本 6 次,以获得我列表中四个项目的所有成对组合 ((1,2), (2,3), (3,4), (1,4), (1,3), (2,4))。
我怎样才能以更有效的方式获得相同的结果,而不是我输入这段代码,但使用不同的数字,6 次?
你可以试试itertools.combinations
。遍历所有 2 元素组合并检查您的条件。如果匹配,您可以将结果附加到存储每个索引对结果的字典中
要检查其余列表的值是否相同(给定组合的 i
、j
除外),您可以在迭代时使用 all
剩余指数:
from itertools import combinations
shared_lists = {}
for line in allLinesList:
indices = set(range(len(line)))
for i, j in combinations(range(len(line)), 2):
remaining = indices - {i, j}
if line[i][4] != "." and line[i][4] == line[j][4] and all(line[i][4] != line[x][4] for x in remaining):
shared_lists.setdefault((i, j), []).append(line[j])
print(shared_lists)
输出
{(0, 1): [['ACmerged_contig_10464', '668', '.', 'A', 'G', '3.87133', '.', 'DP=1;SGB=-0.379885;MQ0F=0;AC=0;AN=2;DP4=0,0,0,1;MQ=28', 'GT:PL', '0/0:28,3,0']]}
我有一个名为 allLinesList
的列表列表,allLinesList
的每一行包含四个列表。这是 allLinesList
[[['ACmerged_contig_10464', '668', '.', 'A', 'G', '3.87133', '.', 'DP=1;SGB=-0.379885;MQ0F=0;AC=0;AN=2;DP4=0,0,0,1;MQ=28', 'GT:PL', '0/0:28,3,0'], ['ACmerged_contig_10464', '668', '.', 'A', 'G', '3.87133', '.', 'DP=1;SGB=-0.379885;MQ0F=0;AC=0;AN=2;DP4=0,0,0,1;MQ=28', 'GT:PL', '0/0:28,3,0'], ['ACmerged_contig_10464', '747', '.', 'T', '.', '84', '.', 'DP=2;MQ0F=0;AN=2;DP4=0,2,0,0;MQ=32', 'GT', '0/0'], ['ACmerged_contig_10464', '747', '.', 'T', '.', '84', '.', 'DP=2;MQ0F=0;AN=2;DP4=0,2,0,0;MQ=32', 'GT', '0/0']],
[['ACmerged_contig_10464', '4', '.', 'T', '.', '29.5864', '.', 'DP=1;MQ0F=0;AN=0;DP4=0,0,0,0;MQ=.', 'GT', './.'], ['ACmerged_contig_10464', '4', '.', 'T', '.', '29.5864', '.', 'DP=1;MQ0F=0;AN=0;DP4=0,0,0,0;MQ=.', 'GT', './.'], ['ACmerged_contig_10464', '4', '.', 'T', '.', '29.5864', '.', 'DP=1;MQ0F=0;AN=0;DP4=0,0,0,0;MQ=.', 'GT', './.'], ['ACmerged_contig_10464', '4', '.', 'T', '.', '29.5864', '.', 'DP=1;MQ0F=0;AN=0;DP4=0,0,0,0;MQ=.', 'GT', './.']]]
allLinesList
总共有几千行。
我想遍历 allLinesList
中的所有这些行,并挑出特定内部列表与其第 5 项共享相同字符的行,只要该字符不是 '.'
.一旦我确定了这样的行,我就会将该行的第一项放入单独的列表中。
例如,在上面的第一个列表中,前两个内部列表共享 'G'
作为它们的第 5 个项目。因此,我想将这些列表之一输出到另一个列表。这将创建另一个列表列表,但只有两层列表,而不是像我的示例那样的三层列表。
我有可以执行此操作的代码,但我认为必须有更有效的方法来执行此操作,也许是使用循环,但我还没有弄清楚。这是我当前的代码:
sharedLists1_2 = []
i = 0
while i < len(allLinesList):
if allLinesList[i][0][4] != "." and allLinesList[i][0][4] == allLinesList[i][1][4] and allLinesList[i][1][4] != allLinesList[i][2][4] and allLinesList[i][1][4] != allLinesList[i][3][4]:
sharedLists1_2.append(allLinesList[i][1])
i +=1
目前,我运行这个代码的版本 6 次,以获得我列表中四个项目的所有成对组合 ((1,2), (2,3), (3,4), (1,4), (1,3), (2,4))。
我怎样才能以更有效的方式获得相同的结果,而不是我输入这段代码,但使用不同的数字,6 次?
你可以试试itertools.combinations
。遍历所有 2 元素组合并检查您的条件。如果匹配,您可以将结果附加到存储每个索引对结果的字典中
要检查其余列表的值是否相同(给定组合的 i
、j
除外),您可以在迭代时使用 all
剩余指数:
from itertools import combinations
shared_lists = {}
for line in allLinesList:
indices = set(range(len(line)))
for i, j in combinations(range(len(line)), 2):
remaining = indices - {i, j}
if line[i][4] != "." and line[i][4] == line[j][4] and all(line[i][4] != line[x][4] for x in remaining):
shared_lists.setdefault((i, j), []).append(line[j])
print(shared_lists)
输出
{(0, 1): [['ACmerged_contig_10464', '668', '.', 'A', 'G', '3.87133', '.', 'DP=1;SGB=-0.379885;MQ0F=0;AC=0;AN=2;DP4=0,0,0,1;MQ=28', 'GT:PL', '0/0:28,3,0']]}