使用python查找并删除公共子字符串
我有两个引物序列: fiveprime = "GATTCGAAGTCCACTATC" threeprime = "TGAGTAGGACGGCACTATC"使用python查找并删除公共子字符串,python,substring,bioinformatics,Python,Substring,Bioinformatics,我有两个引物序列: fiveprime = "GATTCGAAGTCCACTATC" threeprime = "TGAGTAGGACGGCACTATC" 我认为,如果您选择适当的数据结构来表示您试图查找的数据,您的问题将更容易处理。我能想到的最好的是一个 这种结构的好处是,它允许您在给定字母初始序列的情况下表示所有可能的匹配,因此,如果您有序列AABAB,它将允许从初始A到A和B的遍历,但不允许从A到G或T的遍历。这使得查找部分匹配非常有效,因为trie中的任何一点都代表了这么多字母的匹配 此
我认为,如果您选择适当的数据结构来表示您试图查找的数据,您的问题将更容易处理。我能想到的最好的是一个 这种结构的好处是,它允许您在给定字母初始序列的情况下表示所有可能的匹配,因此,如果您有序列AABAB,它将允许从初始A到A和B的遍历,但不允许从A到G或T的遍历。这使得查找部分匹配非常有效,因为trie中的任何一点都代表了这么多字母的匹配 此数据结构类似于:
class Trie(object):
def __init__(self):
self.children = {}
def add_child(self, letter):
if letter in self.children:
return self.children[letter]
else:
child = Trie()
self.children[letter] = child
return child
def traverse(self, letter):
return self.children.get(letter, None)
然后,您可以这样填充:
root = Trie()
current_positions = []
for letter in letters:
current_positions = [
position.add_child(letter)
for position in current_positions
]
current_positions.append(root.add_child(letter))
class TrieSearch(object):
def __init__(self, trie, starting_index):
self.trie = trie
self.starting_index = starting_index
self.ending_index = starting_index + 1
def update(self, letter):
""" This returns a boolean indicating
if the search can accept the letter """
self.trie = self.trie.traverse(letter)
if self.trie is not None:
self.ending_index = self.ending_index + 1
return True
return False
def get_match(self, letters):
return letters[self.starting_index:self.ending_index]
def find_matches(root, letters):
completed_matches = []
current_matches = []
for index, letter in enumerate(letters):
new_current = []
for current in current_matches:
if current.update(letter):
new_current.append(current)
else:
completed_matches.append(current)
new_search_trie = root.traverse(letter)
if new_search_trie is not None:
new_current.append(TrieSearch(new_search_trie, index))
current_matches = new_current
all_matches = completed_matches + current_matches
return [match.get_match(letters) for match in all_matches]
所有这些设置完成后,您应该能够遍历此结构,直到遍历返回null。这将指示最长的当前匹配。字母的初始化将每个字母视为匹配的潜在起点,您也应该如此
然后可以搜索最长的子字符串匹配,如下所示:
root = Trie()
current_positions = []
for letter in letters:
current_positions = [
position.add_child(letter)
for position in current_positions
]
current_positions.append(root.add_child(letter))
class TrieSearch(object):
def __init__(self, trie, starting_index):
self.trie = trie
self.starting_index = starting_index
self.ending_index = starting_index + 1
def update(self, letter):
""" This returns a boolean indicating
if the search can accept the letter """
self.trie = self.trie.traverse(letter)
if self.trie is not None:
self.ending_index = self.ending_index + 1
return True
return False
def get_match(self, letters):
return letters[self.starting_index:self.ending_index]
def find_matches(root, letters):
completed_matches = []
current_matches = []
for index, letter in enumerate(letters):
new_current = []
for current in current_matches:
if current.update(letter):
new_current.append(current)
else:
completed_matches.append(current)
new_search_trie = root.traverse(letter)
if new_search_trie is not None:
new_current.append(TrieSearch(new_search_trie, index))
current_matches = new_current
all_matches = completed_matches + current_matches
return [match.get_match(letters) for match in all_matches]
我将所有这些放在一起,当trie用3prime和5veprime值初始化时,输入数据是cactatcaaaaaaaa,结果是:
['CACTATC', 'ACTATC', 'CTATC', 'TATC', 'ATC', 'TC', 'CA', 'AA', 'AA', 'AA', 'AA', 'AA', 'AA', 'A']
由于您无疑是在处理大量字符串,因此可能需要回顾一些更有效的通用字符串替换算法。这是本文概述的trie方法的扩展。还有使用表而不是trie的。这两种算法都是线性复杂度算法,与longestSubstringFinder方法使用的二次方法相比,这将是一个重大改进。问题是,longestSubstringFinder已损坏。只有当lenmatch>lenanswer:answer=match的条件为False时,才检查lenmatch>lenanswer:answer=match是否匹配。如果rangelen2:循环中的for j结束时没有发生这种情况,则只需放弃匹配
修复方法很简单:在rangelen2:循环中的forj之后添加forj
您最匹配的字符串的长度是多少?您没有在任何地方定义结构变量,但您很乐意附加到它。根据我输入的字符串,可以是任意长度。这就是为什么我要检查找到的公共子字符串的长度。然后用它来比较找到的结构是否是引物的一部分Haa yeah soz关于我刚才复制和粘贴的结构代码结构被定义为结构=[]只是你的正常列表引物的“一部分”是什么?有多少个字符必须匹配?我将尝试一下,我会告诉你一个是否成功。谢谢你的投入和时间!!我已经把代码示例放在一个要点中,你可能想回顾一下。这太好了,非常感谢你真的帮助了我。如果你想让你的代码更好,那就练习,练习,练习:你可能想看看《干净的代码》这本书,了解一些技巧:我明天第一件事就是检查这个,非常感谢你的时间和投入。