#python
Вопрос:
char_complement
смотрит на индекс символа в «вводе» и возвращает букву в том же индексе в «выводе». Если письма нет в списке, возвращается пустое место.
string_complement
предполагается сделать то же самое, но для многочисленных персонажей.
def char_complement(c): input=["A","T","C","G"] output=["T","A","G","C"] if c in input: x= input.index(c) return output[x] return "" def string_complement(s): while s!="": return char_complement(s[0]) str(string_complement(s[1:]))
Если s есть "ATTAGTC"
, "TAATCAGNone"
возвращается.
Комментарии:
1. Какова цель вашего
while
цикла здесь? Выreturn
сразу же, чтобы этот цикл никогда не мог повторяться более одного раза.
Ответ №1:
как говорят другие пользователи: вам нужна return ""
string_complement
функция in в конце
Здесь у меня было некоторое время, чтобы поиграть с проблемой. Я думал, что рекурсия-это элегантный способ решения проблем, но в python есть досадная проблема: ошибка рекурсии (она возникает, когда вы по умолчанию переходите к рекурсии 3000 lvl, и ее можно установить*). Я подумал, что есть лучшие решения, чем использование функции для сортировки каждого символа. Поэтому я решил попробовать решить эту проблему с помощью словаря. И предположив, что вам нужно перевести комбинацию длинных строк, я предложил другие методы. Я придумал 4 разных метода, чтобы попробовать:
#recursive auxFunction #original proposed method def char_complement(c): input=["A","T","C","G"] output=["T","A","G","C"] if c in input: x= input.index(c) return output[x] return "" def string_complement(s): while s!="": return char_complement(s[0]) str(string_complement(s[1:])) return "" #recursive dict def string_complement2(s): char_comp ={'A':'T','T':'A','C':'G','G':'C'} while s!="": return char_comp[s[0]] string_complement2(s[1:]) return "" #comprehension dict def string_complement3(s): char_comp ={'A':'T','T':'A','C':'G','G':'C'} return [char_comp[thisS] for thisS in s] # for dict def string_complement4(s): char_comp ={'A':'T','T':'A','C':'G','G':'C'} complement = "" for thisS in s: complement = char_comp[thisS] return complement
для последнего мне нужно только протестировать все методы и сравнить время выполнения. поэтому я предложил это (возможно, время-не лучшая библиотека для измерения времени между выделениями idk).:
from time import time import numpy as np def test_and_get_times(n): #generate seq atcgList = ['A','T','C','G'] seq = ''.join( np.random.choice(atcgList,n)) try : #to avoid RecursionError t1 = time() a1 = string_complement(seq) t2 = time() a2 = string_complement2(seq) t3 = time() except RecursionError: #if RecursionError set values to nan t2=np.nan t3=np.nan finally: t4 = time() a3 = string_complement3(seq) t5 = time() a4 = string_complement4(seq) t6 = time() return [t2-t1,t3-t2,t5-t4,t6-t5] #diferent lengths to test methods nList = np.arange(10,10001,111) #test all lengths times = np.zeros([4,len(nList)]) for i,n in enumerate(nList): times[:,i] = test_and_get_times(n) #plot results import matplotlib.pyplot as plt plt.figure() plt.plot(nList,times[0],label='Recursive auxFunc') plt.plot(nList,times[1],label='Recursive auxDic') plt.plot(nList,times[2],label='Comprehension auxDic') plt.plot(nList,times[3],label='For auxDic') plt.legend()
запустите код и получите результаты:
Вывод кажется, что использование словаря для получения дополнений быстрее, чем создание вспомогательной функции для того же самого. Использование для понимания или просто для позволяет избежать ошибки рекурсии. и пусть запускают последовательности ларджеров
Извините за мой картофельный английский ( у меня может быть много ошибок в семантике и синтактике)
надеюсь, это может вам как-то помочь! ваше здоровье!
*чтобы установить другое значение для ограничения рекурсии:
import sys sys.setrecursionlimit(desiredValue)
Ответ №2:
Просто добавьте return ""
в конец вашей функции, чтобы при завершении while
цикла возвращалась пустая строка, а не None
:
def string_complement(s): while s!="": return char_complement(s[0]) str(string_complement(s[1:])) return ""
В целом:
def char_complement(c): input=["A","T","C","G"] output=["T","A","G","C"] if c in input: x= input.index(c) return output[x] return "" def string_complement(s): while s!="": return char_complement(s[0]) str(string_complement(s[1:])) return "" print(string_complement("ATTAGTC"))
Выход:
TAATCAG
Ответ №3:
Есть ли необходимость использовать рекурсию? Это можно легко сделать с помощью индексов:
INPUT = ["A","T","C","G"] OUTPUT = ["T","A","G","C"] def get_complement(str_in): letters = list(str_in) return ''.join( [ OUTPUT[INPUT.index(letter)] for letter in letters ] )
Ответ №4:
Проблема решается с помощью однострочного объявления и двух однострочных функций:
COMPLEMENTS = dict(A='T', T='A', C='G', G='C') def char_complement(c): return COMPLEMENTS.get(c, "") def string_complement(s): return ''.join([char_complement(c) for c in s]) print(string_complement("ATTAGTC")) gt;gt;gt;TAATCAG