Список строк, некоторые из которых на самом деле имеют одинаковое содержание (как обрисовано в общих чертах), но с небольшим отличием.
Я хочу найти похожие строки. Возможный способ - использовать коэффициент сходства из SequenceMatcher из ( difflib ).
from difflib import SequenceMatcher
import itertools
mylist = [
"I say,",
"It's in the reach of my arms",
"The span of my hips,",
"The stride of my step,",
"The curl of my lips.",
"I'm a woman",
"Phenomenally.",
"Phenomenal woman,",
"That's me.",
"I say.",
"It's the fire in my eyes,",
"And the flash of my teeth,",
"The swing in my waist,",
"And the joy in my feet.",
"I'm a woman.",
"Phenomenally!",
"Phenomenal women,",
"That's us.",
]
for a, b in itertools.combinations(mylist, 2):
score = SequenceMatcher(None, a, b).ratio()
if score >= 0.90:
print (a + " TO " + b + " : " + str(SequenceMatcher(None, a, b).ratio()))
Вывод:
I'm a woman TO I'm a woman. : 0.9565217391304348
Phenomenally. TO Phenomenally! : 0.9230769230769231
Phenomenal woman, TO Phenomenal women, : 0.9411764705882353
Когда список стало очень длинным, генерация вывода занимает много времени, поэтому я думаю отсортировать список и измерить только сходство ближайших 3 соседей каждой строки / элемента.
Например, для элементов # 1 в отсортированный список, он сравнивает себя только с № 2, № 3, № 4. для элементов № 10 в отсортированном списке он сравнивает себя только с [# 7, # 8, # 9] и [# 11, # 12, # 13].
Итак, я попытался:
mylist.sort(reverse=False)
for num, content in enumerate(mylist):
for a in mylist[num+1:num+4]:
score = SequenceMatcher(None, a, content).ratio()
if score >= 0.90:
print (a + " TO " + content + " : " + score)
for num, content in enumerate(mylist):
if num >= 4:
for a in mylist[num-1:num-4]:
score = SequenceMatcher(None, a, content).ratio()
if score >= 0.90:
print (a + " TO " + content + " : " + str(score))
Намного быстрее это работает с длинным списком. Но мне интересно, есть ли лучший способ? Спасибо.