Как преобразовать рекурсию в возвращение только списка списков - PullRequest
0 голосов
/ 13 февраля 2020

У меня проблема с тем, что мне нужно возвращать список списков, причем каждый вложенный список представляет собой список из 2 строк. Я не могу найти способ эффективно сгладить этот список или вернуть только список списков, так как количество вложенных списков не определено. Это происходит в моей рекурсивной функции, где я разветвляюсь на 3 различных пути рекурсии для каждого рекурсивного l oop. Пока что у меня есть:

def f(used, sequences):
    if sequences[0] == '' or sequences[1] == '':
        if sequences[0] == '' and sequences[1] == '':
            return [used[0], used[1]]
        elif sequences[0] != '':
            return [used[0] + sequences[0], used[1] + '-' * len(sequences[0])]
        elif sequences[1] != '':
            return [used[0] + '-' * len(sequences[1]), used[1] + sequences[1]]
    else:
        return [f([sequences[0][-1] + used[0], sequences[1][-1] + used[1]], [sequences[0][:-1], sequences[1][:-1]]),
        f([sequences[0][-1] + used[0], '-' + used[1]], [sequences[0][:-1], sequences[1]]),
        f(['-' + used[0], sequences[1][-1] + used[1]], [sequences[0], sequences[1][:-1]])]

Я хочу, чтобы выравнивания были всеми возможными выравниваниями двух последовательностей в паре. Однако он создает сложную серию вложенных циклов, которая не может быть определена из-за возможной разной длины последовательностей. Использование вышеуказанной функции как таковой дает:

sequences = ['GAA', 'TGT']
alignments = f(['', ''], sequences)
print(alignments)
>>>[[[['GAA', 'TGT'], ['GAA-', '-GTT'], ['-AAG', 'TGT-']], [['GAA-', 'G-TT'], ['GAA--', '--TTG'], [['G-AA', 'TG-T'], ['G-AA-', '-G-TT'], ['--AAG', 'TG-T-']]], [['A-AG', 'TGT-'], [['GA-A', 'T-GT'], ['GA-A-', '--GTT'], ['-A-AG', 'T-GT-']], ['--AGA', 'TGT--']]], [[['GAA-', 'GT-T'], ['GAA--', '-T-TG'], [['G-AA', 'TGT-'], ['G-AA-', '-GT-T'], ['--AAG', 'TGT--']]], [['GAA--', 'T--TG'], ['GAA---', '---TGT'], [['G-AA-', 'GT--T'], ['G-AA--', '-T--TG'], [['G--AA', 'TGT--'], ['G--AA-', '-GT--T'], ['---AAG', 'TGT---']]]], [[['GA-A', 'TGT-'], ['GA-A-', '-GT-T'], ['-A-AG', 'TGT--']], [['GA-A-', 'G-T-T'], ['GA-A--', '--T-TG'], [['G-A-A', 'TG-T-'], ['G-A-A-', '-G-T-T'], ['--A-AG', 'TG-T--']]], [['A--AG', 'TGT--'], [['GA--A', 'T-GT-'], ['GA--A-', '--GT-T'], ['-A--AG', 'T-GT--']], ['---AGA', 'TGT---']]]], [[['AA-G', 'TGT-'], [['GAA-', 'T-GT'], ['GAA--', '--GTT'], ['-AA-G', 'T-GT-']], ['-A-GA', 'TGT--']], [[['GAA-', 'TG-T'], ['GAA--', '-G-TT'], ['-AA-G', 'TG-T-']], [['GAA--', 'G--TT'], ['GAA---', '---TTG'], [['G-AA-', 'TG--T'], ['G-AA--', '-G--TT'], ['--AA-G', 'TG--T-']]], [['A-A-G', 'TG-T-'], [['GA-A-', 'T-G-T'], ['GA-A--', '--G-TT'], ['-A-A-G', 'T-G-T-']], ['--A-GA', 'TG-T--']]], [['A--GA', 'TGT--'], [['AA--G', 'T-GT-'], [['GAA--', 'T--GT'], ['GAA---', '---GTT'], ['-AA--G', 'T--GT-']], ['-A--GA', 'T-GT--']], ['---GAA', 'TGT---']]]]

, которая будет генерировать что-то вроде [[[['str', 'str'], ['str', 'str'], ['str', 'str']], [['str, 'str']..., когда я хочу, чтобы она выглядела как [['str', 'str'], ['str', 'str'], ['str', 'str']... Есть ли способ исправить мою рекурсию, чтобы это было так , или функцию, которую я могу написать, чтобы выровнять ее так, как я хочу?

Испытав рекомендацию Ch3steR:

def flat(lst):
     if not isinstance(lst[0][0],list):
         return lst
     else:
        return flat(sum(lst,[]))

Я намного ближе к тому, что хочу. Однако внутри все еще есть несколько вложенных циклов.

sequences = ['GAA', 'TGT']
alignments = f(['', ''], sequences)
alignments = flat(alignments)
print(alignments)

Теперь выдает:

[['GAA', 'TGT'], ['GAA-', '-GTT'], ['-AAG', 'TGT-'], ['GAA-', 'G-TT'], ['GAA--', '--TTG'], [['G-AA', 'TG-T'], ['G-AA-', '-G-TT'], ['--AAG', 'TG-T-']], ['A-AG', 'TGT-'], [['GA-A', 'T-GT'], ['GA-A-', '--GTT'], ['-A-AG', 'T-GT-']], ['--AGA', 'TGT--'], ['GAA-', 'GT-T'], ['GAA--', '-T-TG'], [['G-AA', 'TGT-'], ['G-AA-', '-GT-T'], ['--AAG', 'TGT--']], ['GAA--', 'T--TG'], ['GAA---', '---TGT'], [['G-AA-', 'GT--T'], ['G-AA--', '-T--TG'], [['G--AA', 'TGT--'], ['G--AA-', '-GT--T'], ['---AAG', 'TGT---']]], [['GA-A', 'TGT-'], ['GA-A-', '-GT-T'], ['-A-AG', 'TGT--']], [['GA-A-', 'G-T-T'], ['GA-A--', '--T-TG'], [['G-A-A', 'TG-T-'], ['G-A-A-', '-G-T-T'], ['--A-AG', 'TG-T--']]], [['A--AG', 'TGT--'], [['GA--A', 'T-GT-'], ['GA--A-', '--GT-T'], ['-A--AG', 'T-GT--']], ['---AGA', 'TGT---']], ['AA-G', 'TGT-'], [['GAA-', 'T-GT'], ['GAA--', '--GTT'], ['-AA-G', 'T-GT-']], ['-A-GA', 'TGT--'], [['GAA-', 'TG-T'], ['GAA--', '-G-TT'], ['-AA-G', 'TG-T-']], [['GAA--', 'G--TT'], ['GAA---', '---TTG'], [['G-AA-', 'TG--T'], ['G-AA--', '-G--TT'], ['--AA-G', 'TG--T-']]], [['A-A-G', 'TG-T-'], [['GA-A-', 'T-G-T'], ['GA-A--', '--G-TT'], ['-A-A-G', 'T-G-T-']], ['--A-GA', 'TG-T--']], ['A--GA', 'TGT--'], [['AA--G', 'T-GT-'], [['GAA--', 'T--GT'], ['GAA---', '---GTT'], ['-AA--G', 'T--GT-']], ['-A--GA', 'T-GT--']], ['---GAA', 'TGT---']]

1 Ответ

1 голос
/ 13 февраля 2020

Из того, что я понял, я разместил этот ответ.

Вы используете sum, чтобы уменьшить 1 дим вложенного списка.

def flat(lst):
     if not isinstance(lst[0][0],list):
         return lst
     else:
        return flat(sum(lst,[]))

a=[[[['str', 'str'], ['str', 'str'], ['str', 'str']], [['str', 'str']]]]
flat(a)
#[['str', 'str'], ['str', 'str'], ['str', 'str'], ['str', 'str']]

РЕДАКТИРОВАТЬ: для произвольно вложенного списка.

def flat(lst,curr=[]):
    if len(lst)==2 and all(isinstance(i,str) for i in lst):
        return [lst]
    else:
        for i in lst:
            curr=curr+flat(i)
    return curr
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...