При необходимости перебрать многие элементы, itertools , на помощь!
Этот фрагмент будет переставлять все возможности вашей строки (перестановок) и возвращать их так же, как ваш оригиналкод сделал.Я чувствую, что not in
- неоправданно дорогой способ проверки, а не такой питонический.Перестановки были выбраны, так как это дало бы вам максимальный доступ к проверке a-> b или b-> a для двух заданных строк.
import difflib
import itertools
def diff(a, b):
return difflib.SequenceMatcher(None, a, b).quick_ratio()
def calculate_ratios(strings):
dupl = dict()
for s, t in itertools.permutations(strings, 2):
try:
dupl[s].append({t: diff(s,t)})
except KeyError:
dupl[s] = []
dupl[s].append({t: diff(s,t)})
return dupl
a = ['first string', 'second string', 'third string', 'fourth string']
print calculate_ratios(a)
В зависимости от ваших ограничений (поскольку перестановки являются избыточными в вычислительном и пространственном отношении), вы можете заменить перестановки комбинациями, но тогда ваш метод доступа необходимо будет скорректировать (так как ab будет указан только в списке).в a [b], но не в b [a]).
В коде я использую quick_ratio (), но он так же просто изменяется на ratio () или real_quick_ratio () в зависимости от вашего решения, если естьДостаточная точность.
И в таком случае простой IF решит эту проблему:
import difflib
import itertools
def diff(a, b):
return difflib.SequenceMatcher(None, a, b).quick_ratio()
def diff2(a, b):
return difflib.SequenceMatcher(None, a, b).ratio()
def calculate_ratios(strings, threshold):
dupl = dict()
for s, t in itertools.permutations(strings, 2):
if diff(s,t) > threshold: #arbitrary threshhold
try:
dupl[s].append({t: diff2(s,t)})
except KeyError:
dupl[s] = []
dupl[s].append({t: diff2(s,t)})
return dupl
a = ['first string', 'second string', 'third string', 'fourth string']
print calculate_ratios(a, 0.5)