сортировка списков списков для поиска общих вариантов - PullRequest
1 голос
/ 22 октября 2019

У меня есть список списков с именем 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' как их пятый элемент,Следовательно, я хотел бы вывести один из этих списков в другой список. Это создаст другой список списков, но один только с двумя слоями списков, а не с тремя слоями списков, как в моем примере.

У меня есть код, который работает для этого, но я думаю, что должен быть более эффективныйспособ сделать это, возможно, с помощью цикла, который я не понял. Вот мой текущий код:

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 раз?

1 Ответ

1 голос
/ 23 октября 2019

Вы можете попробовать 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']]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...