Take the 2-minute tour ×

I'm looking for a Python module that can do simple fuzzy string comparisons. Specifically, I'd like a percentage of how similar the strings are. I know this is potentially subjective so I was hoping to find a library that can do positional comparisons as well as longest similar string matches, among other things.

Basically, I'm hoping to find something that is simple enough to yield a single percentage while still configurable enough that I can specify what type of comparison(s) to do.

share|improve this question
While not specific to Python, here is a question about similar string algorithms: stackoverflow.com/questions/451884/similar-string-algorithm/… –  Dana Mar 25 '09 at 16:36
possible duplicate of Text difference algorithm –  tzot Sep 20 '10 at 14:08
add comment

closed as primarily opinion-based by noloader, Ed Cottrell, Ian Kemp, Vimsha, TheHippo Feb 7 at 15:28


11 Answers

up vote 140 down vote accepted

Levenshtein Python extension and C library.


The Levenshtein Python C extension module contains functions for fast computation of - Levenshtein (edit) distance, and edit operations - string similarity - approximate median strings, and generally string averaging - string sequence and set similarity It supports both normal and Unicode strings.

import Levenshtein

>>> help(Levenshtein.ratio)

    Compute similarity of two strings.

    ratio(string1, string2)

    The similarity is a number between 0 and 1, it's usually equal or
    somewhat higher than difflib.SequenceMatcher.ratio(), becuase it's
    based on real minimal edit distance.

    >>> ratio('Hello world!', 'Holly grail!')
    >>> ratio('Brian', 'Jesus')

>>> help(Levenshtein.distance)

    Compute absolute Levenshtein distance of two strings.

    distance(string1, string2)

    Examples (it's hard to spell Levenshtein correctly):
    >>> distance('Levenshtein', 'Lenvinsten')
    >>> distance('Levenshtein', 'Levensthein')
    >>> distance('Levenshtein', 'Levenshten')
    >>> distance('Levenshtein', 'Levenshtein')
share|improve this answer
Just wanted to note, for future readers of this thread that happen to be using NLTK in their project, that nltk.metrics.edit_distance('string1', 'string2') will calculate the Levenshtein distance between string1 and string2. So if you're using NLTK like me you might not need to download a Levenshtein library besides this. Cheers –  seafangs Nov 20 '11 at 22:24
now is available via PyPi –  Andrei Kucharavy Jul 22 '13 at 20:30
While NLTK has the edit_distance method, it is pure python. If you are heavily using it, either python-levenshtein or jellyfish can provide a huge speedup... (In my setup I measured >10 times) –  Vajk Hermecz Oct 18 '13 at 1:01
A slightly newer version of the package can be found at pypi.python.org/pypi/python-Levenshtein –  Dennis Oct 24 '13 at 18:13
The PyPi package newly supports Python 3 too (0.11.1) –  Antti Haapala Dec 1 '13 at 19:09
show 1 more comment

difflib can do it.

Example from the docs:

['apple', 'ape']
>>> import keyword
>>> get_close_matches('wheel', keyword.kwlist)
>>> get_close_matches('apple', keyword.kwlist)
>>> get_close_matches('accept', keyword.kwlist)

Check it out. It has other functions that can help you build something custom.

share|improve this answer
+1 Neat, I don't recall ever seeing this before –  Van Gale Mar 25 '09 at 17:07
+1: Great to be introduced to a module I've not used before. –  Jarret Hardie Mar 25 '09 at 17:51
I've actually used difflib before, but found that I couldn't just ask for a percentage match amount. Its been a while though. –  Soviut Mar 25 '09 at 19:33
@Soviut: e.g. difflib.SequenceMatcher(None, 'foo', 'bar').ratio() returns a value between 0-1 which can be interpreted as match percentage. Right? –  utku_karatas Apr 28 '10 at 10:38
You saved me a ton of work by directing me to get_close_matches() –  Renklauf May 8 '12 at 23:39
show 2 more comments

As nosklo said, use the difflib module from the Python standard library.

The difflib module can return a measure of the sequences' similarity using the ratio() method of a SequenceMatcher() object. The similarity is returned as a float in the range 0.0 to 1.0.

>>> import difflib

>>> difflib.SequenceMatcher(None, 'abcde', 'abcde').ratio()

>>> difflib.SequenceMatcher(None, 'abcde', 'zbcde').ratio()

>>> difflib.SequenceMatcher(None, 'abcde', 'zyzzy').ratio()
share|improve this answer
Not terribly impressed by SequenceMatcher. It gives the same score to David/Daved that it gives to David/david. –  Leeks and Leaks May 28 '10 at 18:00
You'll get the same problem with Levenshtein distance. If you don't care about the case, you should just call lower() on each argument before comparing them. –  Barthelemy Apr 28 '11 at 18:00
add comment

Jellyfish is a python module which supports many string comparison metrics including phonetic matching. It's really fast! pure python implementations of Levenstein edit distance are quite slow compared to jellyfishes implementation.

share|improve this answer
This looks like a great library, as it has several string comparison algorithms and not just one: Levenshtein Distance, Damerau-Levenshtein Distance, Jaro Distance, Jaro-Winkler Distance, Match Rating Approach Comparison, Hamming Distance –  Vladtn Jan 27 '12 at 11:35
I'm lazy, clicking links is hard. Examples in the answer would be great. –  CatShoes Apr 25 '13 at 15:08
n.b. Jellyfish doesn't deal well with unicode strings –  sbirch Nov 23 '13 at 21:37
add comment

There is also Google's own google-diff-match-patch ("Currently available in Java, JavaScript, C++ and Python").

(Can't comment on it, since I have only used python's difflib myself)

share|improve this answer
add comment

Another alternative would be to use the recently released package FuzzyWuzzy. The various functions supported by the package are also described in this blogpost.

share|improve this answer
add comment

I am using double-metaphone which works like a charm.

An example:

>>> dm(u'aubrey')
('APR', '')
>>> dm(u'richard')
('RXRT', 'RKRT')
>>> dm(u'katherine') == dm(u'catherine')

Update: Jellyfish also has it. Comes under Phonetic encoding.

share|improve this answer
add comment

Heres the way how it can be done using Charicar's simhash, this is also suitable for long documents, it will detect 100% similarity also when you change order of words in documents too


share|improve this answer
add comment

I've been using Fuzzy Wuzzy from Seat Geek with great success.


Specifically the token set ratio function...

They also did a great write up on the process of fuzzy string matching:


share|improve this answer
add comment

Here's a python script for computing longest common substring in two words(may need tweaking to work for multi-word phrases):

def lcs(word1, word2):

    w1 = set(word1[i:j] for i in range(0, len(word1))
             for j in range(1, len(word1) + 1))

    w2 = set(word2[i:j] for i in range(0, len(word2))
             for j in range(1, len(word2) + 1))

    common_subs = w1.intersection(w2)

    sorted_cmn_subs = sorted([
        (len(str), str) for str in list(common_subs)

    return sorted_cmn_subs.pop()[1]
share|improve this answer
add comment



share|improve this answer
add comment
