Допустим, у меня есть класс Kmerobj с атрибутами: kmer (строка) и locationlist (список)
class Kmerobj(object):
def __init__(self,kmer,locationlist):
self.kmer = kmer
self.locationlist = locationlist
Теперь предположим, что у меня есть какая-то строка, и я повторяю эту строку и создаю все подстроки длины k и сохраняю их как объекты Kmerobj в списке, причем атрибут kmer является подстрокой, а атрибут locationlist является списком начала. сайты этой подстроки. Я написал для этого функцию.
def kmerizeseq(sequence,kmer_size):
kmer_list = []
sequence = sequence.upper()
if (kmer_size <= len(sequence) and kmer_size >= 1):
for start in range(0,len(sequence)-kmer_size+1,1):
kmerseq = sequence[start:start+kmer_size]
if all(kmerseq != kmerobj.kmer for kmerobj in kmer_list):
kmerinst = Kmerobj(kmerseq,[start],list(seq_name))
kmer_list.append(kmerinst)
else:
for kmerobj in kmer_list:
if kmerseq == kmerobj.kmer:
kmerobj.locationlist.append(start)
return kmer_list
Теперь это работает. Если я запустил функцию
kmerizeseq('ATCATC',3)
Я получаю список из трех объектов. Первый имеет kmer-атрибут «ATC» и атрибут locationlist [0,3]. У второго есть kmer-атрибут «TCA» и атрибут locationlist [1]. У третьего есть кмерский атрибут CAT и атрибут locationlist [2].
У меня такой вопрос: есть ли способ добиться того же результата более эффективно? В настоящее время я просматриваю весь список, чтобы определить, имеет ли какой-либо из объектов тот же атрибут kmer, что и вход, затем снова просматриваю список, чтобы найти объект, который соответствует, и изменить его.
Есть ли способ просмотреть список, остановиться, если атрибут kmer текущего объекта совпадает с вводом, и изменить этот объект, а если совпадения не найдено, добавить новый объект kmerobj в список? В идеале мне нужно только один раз перебрать список.
В некоторой степени, хотя только в качестве чтения в файлах fasta (или других типов файлов) и анализа данных для генерации строк последовательности. Я изучу это подробнее и посмотрю, есть ли модуль, который был бы полезен в этом случае.






Question: is there any way to achieve the same outcome more efficiently?
Вам необходим произвольный доступ к Kmerobj с использованием последовательности kmer в качестве ключа.
Рассмотрим следующее, используя dict:
class Kmerobj2(object):
def __init__(self, kmer):
"""Parameter 'kmer' is a tuple of (kmer,index), e.g ('ATC', 0)"""
self.kmer = kmer[0]
self.loc = [kmer[1]]
def append(self, kmer):
self.loc.append(kmer[1])
def locations(self):
return len(self.loc)
def __str__(self):
return "{} => {} location(s) at {}".format(self.kmer, self.locations(), self.loc)
def kmerizeseq2(sequence, kmer_size):
l = []
# Create len(sequence) tuples == (seq, i) with kmer_size in ONE loop
for i, c in enumerate(sequence):
l.append((sequence[i:i + kmer_size], i))
print("[{}]{}".format( len(l), l))
#>>>[6][('ATC', 0), ('TCA', 1), ('CAT', 2), ('ATC', 3), ('TC', 4), ('C', 5)]
d = {}
# Aggregate all equal kmer of len kmer_size
for kmer in l[:(len(sequence)-kmer_size)+1]:
# kmer exists ?
if kmer[0] in d:
# Append kmer.loc to d[kmer]
d[kmer[0]].append(kmer)
else:
# Create a new Kmerobj
d[kmer[0]] = Kmerobj2(kmer)
return d
if __name__ == "__main__":
d = kmerizeseq2('ATCATC',3)
print("type:{}, {}".format(type(d), d))
#>>> type:<class 'dict'>, {'CAT': <__main__.Kmerobj2 object at 0xf70634ec>, 'TCA': <__main__.Kmerobj2 object at 0xf70634cc>, 'ATC': <__main__.Kmerobj2 object at 0xf706348c>}
for kmer in d:
print("{}".format(d[kmer]))
Output:
CAT => 1 location(s) at [2] TCA => 1 location(s) at [1] ATC => 2 location(s) at [0, 3]
Протестировано на Python: 3.4.2
Вы знакомы с биопайтон