Ken*_*nny 21 python list bioinformatics
我刚刚开始学习python,在这里我有一个蛋白质序列的排序列表(总共59,000个序列),其中一些重叠.我在这里制作了一个玩具清单,例如:
ABCDE
ABCDEFG
ABCDEFGH
ABCDEFGHIJKLMNO
CEST
DBTSFDE
DBTSFDEO
EOEUDNBNUW
EOEUDNBNUWD
EAEUDNBNUW
FEOEUDNBNUW
FG
FGH
Run Code Online (Sandbox Code Playgroud)
我想删除那些较短的重叠并保持最长的重叠,以便所需的输出看起来像这样:
ABCDEFGHIJKLMNO
CEST
DBTSFDEO
EAEUDNBNUW
FEOEUDNBNUWD
FGH
Run Code Online (Sandbox Code Playgroud)
我该怎么做?我的代码看起来像这样:
with open('toy.txt' ,'r') as f:
pattern = f.read().splitlines()
print pattern
for i in range(0, len(pattern)):
if pattern[i] in pattern[i+1]:
pattern.remove(pattern[i])
print pattern
Run Code Online (Sandbox Code Playgroud)
我收到了错误消息:
['ABCDE', 'ABCDEFG', 'ABCDEFGH', 'ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDE', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FG', 'FGH']
['ABCDEFG', 'ABCDEFGH', 'ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDE', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FG', 'FGH']
['ABCDEFG', 'ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDE', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FG', 'FGH']
['ABCDEFG', 'ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDE', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FG', 'FGH']
['ABCDEFG', 'ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FG', 'FGH']
['ABCDEFG', 'ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FG', 'FGH']
['ABCDEFG', 'ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FG', 'FGH']
['ABCDEFG', 'ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FGH']
Traceback (most recent call last):
File "test.py", line 8, in <module>
if pattern[i] in pattern[i+1]:
IndexError: list index out of range
Run Code Online (Sandbox Code Playgroud)
sch*_*tte 15
还有其他可行的答案,但没有一个能解释你的实际问题.你真的非常接近有效的解决方案,在我看来,这是最可读的答案.
错误来自于您在检查索引时使用的同一个列表进行了变更range().
因此,在增加i变量的同时,您从列表中删除项目,这一点index error不可避免地导致了这一点.
因此,这是您的初始代码的工作版本,并进行了一些更改,
pattern = ["ABCDE","ABCDEFG","ABCDEFGH","ABCDEFGHIJKLMNO","CEST","DBTSFDE","DBTSFDEO","EOEUDNBNUW","EAEUDNBNUW","FG","FGH"]
output_pattern = []
for i in range(0, (len(pattern)-1)):
if not pattern[i] in pattern[i+1]:
output_pattern.append(pattern[i])
# Adding the last item
output_pattern.append(pattern[-1])
print (output_pattern)
>>>> ['ABCDEFGHIJKLMNO', 'CEST', 'DBTSFDEO', 'EOEUDNBNUW', 'EAEUDNBNUW', 'FGH']
Run Code Online (Sandbox Code Playgroud)
请注意,如果您的列表先前已按照评论部分中的说明进行排序,则此代码将起作用.
这段代码在做什么?
基本上,它使用与初始答案相同的逻辑,它在列表上进行迭代并检查下一个项目是否包含当前项目.但是,使用另一个列表并迭代直到前一个项目,将修复您的索引问题.但是现在出现了一个问题,
我该怎么处理最后一项?
由于列表已排序,您可以将最后一项视为始终唯一.这就是我使用的原因
output_pattern.append(pattern[-1])
Run Code Online (Sandbox Code Playgroud)
这会添加初始列表的最后一项.
重要的提示
这个答案是针对OP的初始问题而写的,他希望保持较长的重叠,并根据同一列表中的下一个项目引用.如@Chris_Rands所述,如果您的顾虑与生物任务有关并需要找到任何重叠,则此解决方案不适合您的需求.
此代码无法识别潜在重叠的示例,
pattern = ["ACD", "AD", "BACD"]
Run Code Online (Sandbox Code Playgroud)
它会输出相同的结果而不删除可能的"ACD"重叠.现在,作为一个澄清,这意味着一个更复杂的算法,我最初认为这超出了问题的要求范围.如果这是你的情况,我可能在这里完全错了,但我真的认为C++实现似乎更合适.看一下@Chris_Rands在评论部分提出的CD-Hit算法.
你可以在这里使用groupby()和max()帮助:
from itertools import groupby
with open('toy.txt') as f_input:
for key, group in groupby(f_input, lambda x: x[:2]):
print(max(group, key=lambda x: len(x)).strip())
Run Code Online (Sandbox Code Playgroud)
这将显示:
ABCDEFGHIJKLMNO
CEST
DBTSFDEO
EOEUDNBNUW
EAEUDNBNUW
FGH
Run Code Online (Sandbox Code Playgroud)
groupby()通过返回基于函数的匹配项列表来工作,在这种情况下,连续的行具有相同的前2个字符.max()然后,该函数获取此列表并返回长度最长的列表项.
| 归档时间: |
|
| 查看次数: |
1500 次 |
| 最近记录: |