Я новичок в Python, и я пытаюсь отфильтровать список последовательностей ДНК (строк) на основе условия.
Учитывая мой случайный список последовательностей ДНК, я хочу сохранить в списке только последовательности, в которых A = T и C = G.
Это то, что я делал до сих пор, но я получаю позицию строки, а не строки. Интересно, как я мог получить строку в моем выводе. Любой совет был бы отличным, спасибо!
Вот что я пытался сделать до сих пор:
import numpy as np
BASES = ('A','C','T','G')
P = (0.2, 0.3, 0.2, 0.3)
def random_dna_sequence(length):
return ''.join(np.random.choice(BASES, p=P) for _ in range(length))
dna = [random_dna_sequence(20) for _ in range(300)] #dna1=300 sequences of 20 characters each
print(dna)
Затем я попытался получить список последовательностей, которые выполняют только это условие:
# Obtain a list dna_2 with DNA sequences that accomplish this condition only
dna_2 = [i for i in range(len(dna)) if (dna[i].count('A'))== (dna[i].count('T')) and (dna[i].count('C'))== (dna[i].count('G'))]
print(dna_2)
Мой вывод возвращает позицию последовательностей, которые выполняют это условие, но не саму последовательность (последовательность):
[29, 41, 66, 85, 88, 117, 142, 174, 201, 226, 231, 246, 250, 279, 294, 299, 306, 338, 370, 372, 381, 404, 420, 486, 519, 579]
И результат моего желания должен быть:
['AACTGACTTG', ...]
Спасибо вам всем!
dna_2 = [i for i in range(len(dna)) if (dna[i].count('A'))== (dna[i].count('T')) and (dna[i].count('C'))== (dna[i].count('G'))]
i
здесь относится к индексу (который вы, вероятно, знаете, но ошиблись, поскольку вы находятся использовали dna[i]
при вызове .count
).
Вы можете изменить его на dna_2 = [dna[i] for i ...]
или еще лучше, просто перебирая строки последовательности напрямую, вместо того, чтобы поверхностно использовать индексы:
dna_2 = [sequence for sequence in dna if sequence.count('A') ... ]
Большое вам спасибо за ваше объяснение! Я не понимал, что вы тоже дали мне решение: D Всем спасибо!
Которые должны быть
dna_2 = [dna[i] for i in range(len(dna)) if (dna[i].count('A'))== (dna[i].count('T')) and (dna[i].count('C'))== (dna[i].count('G'))]
вместо.
Вы спрашиваете или отвечаете?
Хорошо, отвечаю ;-)
Спасибо большое за вашу помощь. Это именно то, что я искал. Я неправильно использовал индекс i в формуле. Спасибо!! :)
Для более элегантного решения просто перебирайте список, а не индекс:
dna_2 = [this_dna for this_dna in dna if (this_dna.count('A'))== (this_dna.count('T')) and (this_dna .count('C'))== (this_dna.count('G'))]
Вы можете просто использовать функцию фильтра с лямбда-выражением. Алгоритм функции фильтра оптимизирован под капотом.
Однако вам следует изучить синтаксис лямбда. Лямбды - это просто встроенные функции.
Вот синтаксис вашей проблемы:
random_dna_sequencies = [random_dna_sequence(20) for _ in range(300)]
filtered_dna_sequencies_iterator = filter(lambda dna_sequency:
dna_sequency.count('A') == dna_sequency.count('T') and
dna_sequency.count('C') == dna_sequency.count('G'),
random_dna_sequencies)
filtered_dna_sequencies_list = list(filtered_dna_sequencies_iterator)
print(filtered_dna_sequencies_list)
Позволь мне объяснить:
filter()
получает два параметра:
random_dna_sequencies
(что означает каждую последовательность ДНК) передается лямбда-функции в качестве аргумента с именем dna_sequency
. Паметер протестирован в состоянии dna_sequency.count('A') == dna_sequency.count('T') and dna_sequency.count('C') == dna_sequency.count('G')
. В переменную filtered_dna_sequencies_iterator
возвращаются только те, кто удовлетворяет условию.filter()
возвращает итератор, а не список. Если вы хотите, чтобы объект помещал его только в цикл for
, используйте итератор. Если вы хотите сохранить объект в списках, используйте приведение filtered_dna_sequencies_list = list(filtered_dna_sequencies_iterator)
.
Во втором понимании списка вам понадобится dna [i] for i in ...