Новичок в Python - список фильтров по условию

Я новичок в 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 [i] for i in ...

norie 30.03.2021 01:17
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
40
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий
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 Всем спасибо!

Marta Fredes 30.03.2021 01:34

Которые должны быть

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'))]

вместо.

Вы спрашиваете или отвечаете?

DeepSpace 30.03.2021 01:23

Хорошо, отвечаю ;-)

Dave Atkinson 30.03.2021 01:25

Спасибо большое за вашу помощь. Это именно то, что я искал. Я неправильно использовал индекс i в формуле. Спасибо!! :)

Marta Fredes 30.03.2021 01:30

Для более элегантного решения просто перебирайте список, а не индекс:

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'))]

функция filter () -> прирост производительности

Вы можете просто использовать функцию фильтра с лямбда-выражением. Алгоритм функции фильтра оптимизирован под капотом.

Однако вам следует изучить синтаксис лямбда. Лямбды - это просто встроенные функции.

Вот синтаксис вашей проблемы:

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)

Позволь мне объяснить:

  1. функция filter() получает два параметра:
    1. Второй параметр - это итератор / список, который вы хотите отфильтровать.
    2. Первый параметр - это лямбда-выражение. Каждый элемент из списка 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 возвращаются только те, кто удовлетворяет условию.
  2. функция filter() возвращает итератор, а не список. Если вы хотите, чтобы объект помещал его только в цикл for, используйте итератор. Если вы хотите сохранить объект в списках, используйте приведение filtered_dna_sequencies_list = list(filtered_dna_sequencies_iterator).

Другие вопросы по теме