많은 항목을 반복 할 필요가있을 때 itertools!
이 스 니펫은 문자열의 모든 가능성을 순열 (permutations)하여 원본 코드와 같은 방식으로 반환합니다. 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는 만 나열되기 때문에 (조정해야합니다 [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)
입니다. 여기서해야 할 일은 실제 병목 현상을 파악하는 것입니다. 제 생각에'SequenceMatcher.ratio()'는 꽤 비싸므로 대신 quick_ratio() 또는 real_quick_ratio()를 사용하는 것이 좋습니다. –
또한'SequenceMatcher'를 사용하는 이유가 있습니까? 아마도 'quick_ratio'와 같이 문서화가 잘 안되는 함수를 사용하지 않고 문제에 최적화 된 차이 메트릭을 제공 할 수 있습니다. 문제의 문맥을 이해하는 데 도움이 될 것입니다 : 각각의 문자열이 얼마나 오래 되었는가, 그것이 유사하다면 왜 중요한가, 어떤 점에서 유사성을 정의하고 싶습니까? –
'quick_ratio'는' ratio' ... anagrams의 비율은 특히 문제가 있습니다. 예를 들어'quick_ratio'는'1.0'이지만'ratio'는'0.375'입니다. 그러나 상한선을 제공하므로 양쪽 모두를 할 수 있습니다. 'quick_ratio'를 사용하여 분명히 다른 문자열을 신속하게 제거한 다음, 더 비싼 '비율'을 남은 것에 사용하십시오. 분명히 이것을 프로파일 링하고, 최악의 경우에는 느려질 수 있습니다. – cha0site