from collections import defaultdict
from pprint import pprint
data = [w.strip() for w in "BSNREORG, BSNWA010".split(',')]
alphabet = set(c for w in data for c in w)
nxt = {}
for c in alphabet:
tmp = [w for w in data if c in w]
if len(tmp) > 1:
nxt[c] = tmp
pprint(nxt)
while nxt:
cur, nxt = nxt, defaultdict(set)
for k, v in cur.items():
for c in alphabet:
for pattern in {k + c, c + k}:
nxt[pattern].update(w for w in v if pattern in w)
nxt = {k: v for k, v in nxt.items() if len(v) > 1}
pprint(dict(cur))
s = "abababa" # для определённости
j = -1
array = [-1] # здесь в позиции [i+1] будет длина наибольшего префикса
# который заканчивается буквой по индексу [i]
# (только не префикса, начинающегося с начала строки -
# а так-то целая строка сама себе префикс, и суффикс, и инфикс)
for i, c in enumerate(s):
while j != -1 and c != s[j]:
j = array[j] # вот эта операция равносильна декременту j (для неотрицательных)
# посмотри на print
j += 1 # если текущая буква встречается впервые - длина префикса будет 0
array.append(j)
print(i, array) # это просто пошаговый вывод
0 [-1, 0]
1 [-1, 0, 0]
2 [-1, 0, 0, 1] - вот, по индексу 2 у нас 'a' - с неё и начинается s
вышли из цикла, инкрементировали j
3 [-1, 0, 0, 1, 2] - по индексу 3 у нас 'b' == s[1] - инкрементировали j
и добавили в хвост
4 [-1, 0, 0, 1, 2, 3]
5 [-1, 0, 0, 1, 2, 3, 4]
6 [-1, 0, 0, 1, 2, 3, 4, 5] - смотри, тут мы много раз подряд
пролетали мимо тела цикла while, и j росла синхонно с i
a = array[-1] # это мы получили длину префикса который также и суффикс.
if array.count(a) < 2: # но если столь же длинного инфикса нет -
a = array[a] # мы просто прирежем префикс покороче,
# который также является суффиксом, но более коротким
if a > 0:
print(s[:a])
else:
print("Just a legend")
def truncate(f, n):
s = "%.20f" % f
return s[:s.find('.') + n + 1]
test = [{'ключ1': 'ABCDE', 'ключ2': '12345'}, {'ключ1': 'QWERT', 'ключ2': '12345'}]
print(next(i for i, d in enumerate(test) if d.get('ключ1') == 'QWERT'))
from itertools import cycle
for c in cycle(['A', 'B', 'C']):
print(c)
from itertools import count
lst = ['A', 'B', 'C']
for i in count():
print(i, lst[i % len(lst)])
from os import walk, path
for pth, _, files in walk("/дирек/то/рия"):
for name in files:
if name.lower().endswith(".txt"):
fullname = path.join(pth, name)
with open(fullname) as f:
buf = f.read()
with open(fullname[:-3] + "csv", "w") as f:
f.write("за,го,лов,ки\n")
f.write(buf)
return eval("1")
. eval
вообще может лишь вычислять выражения, что-то более сложное делает exec
.