Есть ли способ получить общие подстроки, образующие начало списка строк? Длина подстроки должна быть больше 1.
Например, если есть список L:
[ "hello", "help", "helium", "habit", "habitat", "hazard"]
На выходе должно быть частотное распределение:
he - 3
hel - 3
habit - 2
ha - 3
Позже я могу удалить дубликаты, образованные теми же строками, снова применив ту же логику, чтобы просмотреть общие начальные подстроки из распределения, проверить их количество и, если количество одинаковое, рассмотреть только самую длинную строку.
т. е. мы получаем «он» и «хель», образованные одним и тем же набором слов, имеющих одинаковые значения. Следовательно, выбираем только "hel", так как это самая длинная строка
вы можете использовать collections.Counter
для подсчета повторений подстрок, и вам просто нужно создавать подстроки самостоятельно.
один вкладыш должен был бы создать потребляемые подстроки с помощью itertools.chain.from_iterable
, что объединило бы генераторы подстрок в один длинный генератор для счетчика, потребляемого следующим образом.
from collections import Counter
from itertools import chain
input_list = [ "hello", "help", "helium", "habit", "habitat", "hazard"]
counter = Counter(
chain.from_iterable(
(entry[:i] for i in range(2,len(entry))) for entry in input_list
)
)
counter_filtered = {x:y for x,y in counter.items() if y != 1} # remove single entries
print(counter_filtered)
{'he': 3, 'hel': 3, 'ha': 3, 'hab': 2, 'habi': 2}
Или, если вы хотите использовать Itertools, мы можем пойти дальше: chain.from_iterable(islice(accumulate(entry), 1, None) for entry in input_list)
@KellyBundy это самый чистый и самодокументируемый код, который я мог придумать, вложенные предложения for
обычно очень запутаны (по крайней мере, для меня), а полная реализация itertools не кажется мне очень описательной, в конце день между ними вряд ли есть заметная разница в производительности, поэтому мы должны выбрать наиболее читаемый, главное, чего я хотел избежать с помощью этого однострочника, — это избежать вызова counter.update
в цикле, который обычно был бы намного медленнее.
Я бы сказал, что если вы хотите чистоты и удобочитаемости, вам не нужен такой длинный лайнер :-). Для ясности, или для других, это то, что я имел в виду.
Зачем цепочка, если можно просто использовать два предложения
for
?