#python #for-loop #split #iterator #pattern-matching
#питон #для цикла #сплит #итератор #сопоставление с образцом
Вопрос:
У меня есть текстовый файл, который выглядит как:
>MN00153:75:000H37WNG:1:11102:13823:1502
CCTGCGTTGAAGTGGCTTACTTGCACCTTATGCTACCGTGACCTGCGAATCCAGTCTCATCGTGACCATTCAGGACCAGTGGCAAGAGATCGGAAGAGCACACGTCTGAACTCCAGTCACCGCTCATTATCTCGTATGCCGTCTTCTGCTT
CASP3_fw1_rc : CCATTCAGGACCAGTGGCAAG - The position is 66
CASP3_fw2 : CCTGCGTTGAAGTGGCTTACT - The position is 1
Distance is 44
>MN00153:75:000H37WNG:1:11102:13823:1504
CCTGCGTTGAAGTGGCTTACTTGCACCTTATGCTACCGTGACCTGCGAATCCAGTCTCATCGTGACCATTCAGGACCAGTGGCAAGAGATCGGAAGAGCACACGTCTGAACTCCAGTCACCGCTCATTATCTCGTATGCCGTCTTCTGCTT
CASP3_fw1_rc : CCATTCAGGACCAGTGGCAAG - The position is 66
CASP3_fw2 : CCTGCGTTGAAGTGGCTTACT - The position is 1
Distance is 44
>MN00153:75:000H37WNG:1:11102:13823:1506
CCTGCGTTGAAGTGGCTTACTTGCACCTTATGCTACCGTGACCTGCGAATCCAGTCTCATCGTGACCATTCAGGACCAGTGGCAAGAGATCGGAAGAGCACACGTCTGAACTCCAGTCACCGCTCATTATCTCGTATGCCGTCTTCTGCTT
CASP3_fw1_rc : CCATTCAGGACCAGTGGCAAG - The position is 66
CASP3_fw2_rc : CCTGCGTTGAAGTGGCTTACT - The position is 1
Distance is 44
>MN00153:75:000H37WNG:1:11102:13823:1508
CCTGCGTTGAAGTGGCTTACTTGCACCTTATGCTACCGTGACCTGCGAATCCAGTCTCATCGTGACCATTCAGGACCAGTGGCAAGAGATCGGAAGAGCACACGTCTGAACTCCAGTCACCGCTCATTATCTCGTATGCCGTCTTCTGCTT
CASP3_fw1_rc : CCATTCAGGACCAGTGGCAAG - The position is 66
EIF2_fw2 : CCTGCGTTGAAGTGGCTTACT - The position is 1
Distance is 44
Меня интересуют строки 3 и 4 каждого сегмента (начинаются с ‘>’). Я хочу посчитать 1, если строка 3 и строка 4 — это CASP3 (независимо от того, что будет потом). таким образом, результат должен быть
3
Потому что первый, второй и третий сегменты имеют пару CASP3 в строках 3 и 4 каждого сегмента (кроме последнего).
Спасибо
Ответ №1:
Если ваш файл не слишком велик, вы можете использовать .readlines
функцию для получения list
строк следующим образом:
with open('filename.txt', 'r') as f:
lines = f.readlines()
затем используйте enumerate
и str
методы следующим образом:
cnt = 0
for inx, line in enumerate(lines):
if line.startswith('>') and lines[inx 2].startswith('CASP3') and lines[inx 3].startswith('CASP3'):
cnt = 1
print(cnt)
Мое решение требует , чтобы после последней строки было не менее 3 строк , начинающихся с >
.
Комментарии:
1. Спасибо за ваше отличное решение. Можно ли было бы использовать ваш код также таким образом, чтобы if
[inx 2]
и[inx 3]
не были похожи (только часть перед первой_
), а затем получить счетчик для этого?
Ответ №2:
Без чтения всего файла в память:
def startswith_casp(iterator):
# grab the next four lines of your file
chunk = [line for _, line in zip(range(3), iterator)]
# use a slice here to avoid index errors
return all(c.startswith('CASP3') for c in chunk[1:3])
with open('yourfile.txt') as fh:
count = 0
for line in fh:
if not line.strip():
continue
elif line.startswith('>'):
# Function returns a boolean, so True will add 1 while False adds 0
count = startswith_casp(fh)
else:
continue
print(count)
Ответ №3:
Здесь я split
использую by nn
, чтобы получить «ведра», затем by n
, чтобы получить строки внутри каждого ведра, затем проверяю 3-ю ( [2]
) и 4-ю ( [3]
) строки в каждом ведре на наличие шаблона:
with open('genes.txt') as file:
data = file.read()
by_bucket = [i.split('n') for i in data.split('nn')]
count = 0
for bucket in by_bucket:
count = (bucket[2].startswith('CASP3') and bucket[3].startswith('CASP3'))
print(count)
Ответ №4:
Вероятно, это помогло бы, если бы вы объяснили, что вы уже пробовали. Это, как говорится, вот общий подход:
- Используйте этот
.split()
метод для разделения на любые символы, которые вы хотите. В результате вы получите список, в котором каждая запись будет представлять собой одно ведро. - Просмотрите этот список с
for VariableName in ExampleList:
помощью, чтобы проверить каждое ведро самостоятельно. - При желании вы можете проверить, является ли первая запись a
>
, или если вы правильно выполнили разделение, возможно, вам это и не понадобится. - Разделите каждое ведро в другой список , где каждая запись занимает одну строку , используя
bucket.splitlines()
. - Затем проверьте, соответствуют ли первые символы 3-й и 4-й записи в этом списке
CASP3
, проверив, являются лиstring[2][:5]=="CASP3"
(для третьей строки) иstring[3][:5]=="CASP3"
(для четвертой строки) истинными. - Добавьте к функции еще один счетчик, который увеличивается на 1 всякий раз, когда допустимо одно ведро.
- верните этот счетчик.
Если у вас есть дополнительные вопросы, не стесняйтесь задавать их.
Вот пример, который принимает строку и возвращает нужное вам значение:
def getValue(string):
counter=0
splitList=string.split("nn")
for bucket in splitList:
bucket=bucket.splitlines()
if bucket[2][:5]=="CASP3" and bucket[3][:5]=="CASP3":
counter =1
return counter
Обратите внимание, что эта функция зависит от того, что сегменты разделяются пустой новой строкой, но вы также можете изменить это, чтобы отделить любые другие символы.
Ответ №5:
Мое решение заключается в чтении file.txt в словарь текстовых разделов (где раздел занимает промежуток между двумя символами больше, чем (например, ‘>’), что затем позволяет вам легко выполнять некоторые сравнения.
file_path = './file.txt'
keyword="CASP3"
section_ID = 0
count = 0
all_sections = {}
with open(file_path,'r') as f:
for line in f:
if line.startswith(">"):
if line not in all_sections:
section_ID = 1
all_sections[section_ID] = {}
all_sections[section_ID]['entries'] = []
all_sections[section_ID]['entries'].append(line)
for sec_id in all_sections:
if all_sections[sec_id]['entries'][2].startswith(keyword) and all_sections[sec_id]['entries'][3].startswith(keyword):
count =1
print('count : ', count)
вывод с использованием вашего файла будет :
количество: 3