- ВКонтакте
- РћРТвЂВВВВВВВВнокласснРСвЂВВВВВВВВРєРСвЂВВВВВВВВ
- РњРѕР№ Р В Р’В Р РЋРЎв„ўР В Р’В Р РЋРІР‚ВВВВВВВВРЎР‚
- Viber
- Skype
- Telegram
Не выводится третий символ
Задача следующая:
На входе вводится строка из букв, следующим вводим число, которое будет означать длину последовательности, чьи варианты будут искаться в строке.
Нужно вывести все варианты в виде списка. Например, если введём
AFGTYAFTGAF
, а затем ввёдем число2
, то нужно будет ввести все уникальные встречаемые варианты без повторов, точнее:AF, FG, GT, GY
и так далее.
У меня следующий код:
seq = input().upper()
k_mer = int(input())
list = []
n = 0
for i in seq:
seq = seq[n:len(seq)]
k = seq[0:k_mer]
if k not in list and k != '':
list.append(k)
n += 1
print(list)
Начал с проверки для числа 1
и уже не получается.
Так, при вводе, например, AGTC
, код почему-то не видит третью букву Т
при числе, но если строку удлинить до AGTCAGTC
, только тогда выведет и то в последнюю очередь.
При чём использовать нужно только самые простые функции типа append
, find
, for
.
Ответы (3 шт):
При сокращении строки внутри цикла с помощью seq = seq[n:len(seq)]
, строка постоянно укорачивается:
seq = input().upper()
k_mer = int(input())
unique_kmers = []
for n in range(len(seq) - k_mer + 1):
k = seq[n:n + k_mer]
if k not in unique_kmers:
unique_kmers.append(k)
print(unique_kmers)
Готовый консольный скрипт (сохранить в файл test.py и запустить):
import os
print("-" * 70 + "\nСписок уникальных комбинаций заданной длины из букв заданной строки:\n" + "-" * 70)
# Функция обработки строки:
def unique_substrings(v_string, v_n):
ok = True
if not v_string: print("Не указана строка!"); ok = False
if ok:
try: v_string = v_string.strip()
except Exception as e: print(f"Недопустимое содержимое строки! Подробнее:\n{e}"); ok = False
if ok:
try: v_n = abs(int(v_n))
except Exception as e: print(f"Недопустимое значение длины подстрок! Подробнее:\n{e}"); ok = False
if ok and (v_n <= 0 or v_n > len(v_string)): print("Недопустимое значение длины подстрок!"); ok = False
if ok:
set_substrings = set()
for i in range(len(v_string) - v_n + 1): set_substrings.add(v_string[i: i + v_n])
print(f"\nСписок уникальных комбинаций букв по {v_n}:\n", list(set_substrings))
# Пример использования:
v_string = "AFGTYAFTGAF"
v_n = 4
unique_substrings(v_string, v_n)
print("\nНажмите любую клавишу для продолжения...")
os.system("pause > nul" if os.name == "nt" else "read > /dev/null")
Результат:
Список уникальных комбинаций букв по 4:
['FGTY', 'AFGT', 'FTGA', 'TYAF', 'TGAF', 'GTYA', 'YAFT', 'AFTG']
Добавляем отладочную печать:
...
seq = seq[n:len(seq)]
print('seq', seq, 'n', n) # отладка
k = seq[0:k_mer]
...
$ echo -e 'AGTC\n1' | python temp.py seq 'AGTC' n 0 seq 'GTC' n 1 seq 'C' n 2 seq '' n 3 ['A', 'G', 'C'] $ echo -e '112123123412345123456\n1' | python temp.py seq '112123123412345123456' n 0 seq '12123123412345123456' n 1 seq '123123412345123456' n 2 seq '123412345123456' n 3 seq '12345123456' n 4 seq '123456' n 5 seq '' n 6 seq '' n 7 seq '' n 8 seq '' n 9 seq '' n 10 seq '' n 11 seq '' n 12 seq '' n 13 seq '' n 14 seq '' n 15 seq '' n 16 seq '' n 17 seq '' n 18 seq '' n 19 seq '' n 20 ['1']
Второй пример показывает проблему: сперва от строки отщипывается один символ (всё в порядке), затем два (значит один пропустили), затем три (два пропустили). Скоро строка кончается, и цикл работает в холостую, но это уже не важно. Откусывать надо по одному символу и делать это в конце цикла:
...
for i in seq:
print('seq', repr(seq), 'n', n) # отладка
k = seq[0:k_mer]
if k not in list and k != '':
list.append(k)
n += 1
seq = seq[1:len(seq)] # один символ долой
...
$ echo -e 'AGTC\n1' | python temp.py seq 'AGTC' n 0 seq 'GTC' n 1 seq 'TC' n 2 seq 'C' n 3 ['A', 'G', 'T', 'C'] $ echo -e '112123123412345123456\n1' | python temp.py seq '112123123412345123456' n 0 seq '12123123412345123456' n 1 seq '2123123412345123456' n 2 seq '123123412345123456' n 3 seq '23123412345123456' n 4 seq '3123412345123456' n 5 seq '123412345123456' n 6 seq '23412345123456' n 7 seq '3412345123456' n 8 seq '412345123456' n 9 seq '12345123456' n 10 seq '2345123456' n 11 seq '345123456' n 12 seq '45123456' n 13 seq '5123456' n 14 seq '123456' n 15 seq '23456' n 16 seq '3456' n 17 seq '456' n 18 seq '56' n 19 seq '6' n 20 ['1', '2', '3', '4', '5', '6']
Так гораздо лучше. Только медленно. Не надо менять строку, из неё можно вырезать подходящие кусочки:
...
for i in range(len(seq) - k_mer + 1):
k = seq[i:i + k_mer]
if k not in list and k != '':
list.append(k)
n += 1
...
Стало быстрее, но k not in list
всё ещё может тормозить на длинных списках. Заменим на множество, код станет быстрее и проще:
seq = input().upper()
k_mer = int(input())
s = set()
for i in range(len(seq) - k_mer + 1):
s.add(seq[i:i + k_mer])
lst = list(s)
print(lst)
$ echo -e 'AFGTYAFTGAF\n1' | python temp.py ['A', 'G', 'Y', 'T', 'F'] $ echo -e 'AFGTYAFTGAF\n2' | py temp.py ['TY', 'YA', 'GA', 'GT', 'TG', 'FT', 'FG', 'AF']