### Install Levenshtein from Git Source: https://github.com/rapidfuzz/levenshtein/blob/main/docs/installation.md Clone the repository and install Levenshtein locally if you need to work on the library or use the latest development version. ```sh git clone https://github.com/rapidfuzz/Levenshtein.git cd Levenshtein pip install . ``` -------------------------------- ### Levenshtein Module Import and Usage Example Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Demonstrates how to import the Levenshtein module and use its core functions without additional setup. All exported functions are available immediately upon import. ```python import Levenshtein # All of these work without additional setup Levenshtein.distance("a", "b") Levenshtein.median(["a", "b"]) Levenshtein.StringMatcher() ``` -------------------------------- ### Type Hinting Examples for Levenshtein Functions Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/types.md Demonstrates how to use type hints with Levenshtein functions for mypy/pyright compatibility. Includes examples for distance, ratio, and editops. ```python # Type hints work with all functions from typing import Sequence from collections.abc import Hashable distance_result: int = distance("hello", "hallo") ratio_result: float = ratio("hello", "hallo") editops_result: list[tuple[str, int, int]] = editops("hello", "hallo") ``` -------------------------------- ### Install Levenshtein Package Source: https://github.com/rapidfuzz/levenshtein/blob/main/README.md Use this command to install the Levenshtein package. Ensure you have Python 3.10 or later. ```bash pip install levenshtein ``` -------------------------------- ### StringMatcher Usage Example Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Demonstrates typical usage of the StringMatcher class, including initialization, retrieving various similarity metrics and edit information, and updating sequences. ```python from Levenshtein import StringMatcher # Create matcher with initial sequences matcher = StringMatcher(seq1="spam", seq2="park") # Get various metrics and operations print(f"Distance: {matcher.distance()}") # 3 print(f"Similarity: {matcher.ratio()}") # ~0.4286 print(f"Quick estimate: {matcher.real_quick_ratio()}") # 0.5 # Get detailed edit information print(f"Editops: {matcher.get_editops()}") print(f"Opcodes: {matcher.get_opcodes()}") print(f"Matching blocks: {matcher.get_matching_blocks()}") # Update sequences matcher.set_seqs("spam", "spaz") print(f"New distance: {matcher.distance()}") # 1 ``` -------------------------------- ### Levenshtein Matching Blocks Example Source: https://github.com/rapidfuzz/levenshtein/blob/main/docs/levenshtein.md Demonstrates how to use matching_blocks with editops to find commonalities between two strings. The last zero-length block is for difflib compatibility. ```python >>> a, b = 'spam', 'park' >>> matching_blocks(editops(a, b), a, b) [(1, 0, 2), (4, 4, 0)] >>> matching_blocks(editops(a, b), len(a), len(b)) [(1, 0, 2), (4, 4, 0)] ``` -------------------------------- ### Get Matching Blocks Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Retrieve a list of tuples representing matching blocks between the two sequences. Each tuple contains the start position in sequence 1, start position in sequence 2, and the length of the match. The result is cached internally. ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") blocks = matcher.get_matching_blocks() print(blocks) # Output: [(1, 0, 2), (4, 4, 0)] ``` -------------------------------- ### Levenshtein Algorithm Selection Guide Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/README.md A guide to selecting the appropriate Levenshtein function based on the desired outcome, such as numeric distance, normalized similarity, or identifying changes. ```text What do you want? ├─ Numeric distance? → distance() ├─ Normalized similarity? → ratio() ├─ Quick comparison? → hamming() or jaro_winkler() ├─ See what changed? → editops() or opcodes() ├─ Find representative string? → median() or setmedian() └─ Compare lists? → setratio() or seqratio() ``` -------------------------------- ### Get Quick Ratio Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Retrieves the similarity ratio, identical to the ratio() method. This method is provided for compatibility with difflib.SequenceMatcher. ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") sim = matcher.quick_ratio() print(sim) # Same as ratio() ``` -------------------------------- ### Levenshtein Library Build Configuration Source: https://github.com/rapidfuzz/levenshtein/blob/main/src/Levenshtein/CMakeLists.txt Configures the Levenshtein C++ library build. This includes creating the Cython target, adding the Python library, setting C++ standard, include directories, linking dependencies, and installing the target. ```cmake create_cython_target(levenshtein_cpp) rf_add_library(levenshtein_cpp ${levenshtein_cpp} ${LEV_BASE_DIR}/Levenshtein-c/_levenshtein.cpp) target_compile_features(levenshtein_cpp PUBLIC cxx_std_17) target_include_directories(levenshtein_cpp PRIVATE ${LEV_BASE_DIR}/Levenshtein-c) target_link_libraries(levenshtein_cpp PRIVATE rapidfuzz::rapidfuzz) install(TARGETS levenshtein_cpp DESTINATION Levenshtein/) ``` -------------------------------- ### Get Editops List Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/types.md Demonstrates how to obtain a list of edit operations in the 3-tuple format using the `editops` function. This format is useful for detailed, step-by-step analysis of differences between strings. ```python from Levenshtein import editops # Get editops ops: list[tuple[str, int, int]] = editops('spam', 'park') # Result: [('delete', 0, 0), ('insert', 3, 2), ('replace', 3, 3)] for operation, spos, dpos in ops: print(f"{operation} at source:{spos} destination:{dpos}") ``` -------------------------------- ### Handle Missing Dependencies (ImportError) Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/errors.md Catches ImportError or ModuleNotFoundError when the required rapidfuzz package is not installed. Install with 'pip install "rapidfuzz>=3.9.0,<4.0.0"'. ```python try: import Levenshtein except ImportError as e: print(f"Could not import: {e}") ``` -------------------------------- ### Subtracting Edit Subsequence Example Source: https://github.com/rapidfuzz/levenshtein/blob/main/docs/levenshtein.md Illustrates subtracting an edit subsequence from a sequence using subtract_edit. The result is equivalent to applying the remaining edits. ```python >>> e = editops('man', 'scotsman') >>> e1 = e[:3] >>> bastard = apply_edit(e1, 'man', 'scotsman') >>> bastard 'scoman' >>> apply_edit(subtract_edit(e, e1), bastard, 'scotsman') 'scotsman' ``` -------------------------------- ### Get Opcodes Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Retrieve the list of opcodes representing the differences between the two sequences. The result is cached internally after the first call. ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") opcodes = matcher.get_opcodes() for op, s1_start, s1_end, s2_start, s2_end in opcodes: print(f"{op}: {s1_start}-{s1_end} -> {s2_start}-{s2_end}") ``` -------------------------------- ### Get Real Quick Ratio Estimate Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Calculates a fast, rough upper bound estimate of the similarity ratio using the formula: 2.0 * min(len1, len2) / (len1 + len2). ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") est = matcher.real_quick_ratio() print(est) ``` -------------------------------- ### Show What Changed Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/README.md Determine the edit operations required to transform one string into another using the `editops` function. It returns a list of tuples, where each tuple describes an operation (insert, delete, or replace), the starting position in the source string, and the starting position in the destination string. ```python from Levenshtein import editops ops = editops("spam", "park") for op, spos, dpos in ops: print(f"{op}: {spos} -> {dpos}") ``` -------------------------------- ### Get Matching Blocks Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/types.md Shows how to find identical contiguous blocks between two strings using `matching_blocks`. It requires the edit operations and the original strings as input, returning positions and lengths of matches. ```python from Levenshtein import editops, matching_blocks # Get matching blocks a, b = 'spam', 'park' blocks: list[tuple[int, int, int]] = matching_blocks(editops(a, b), a, b) # Result: [(1, 0, 2), (4, 4, 0)] for s1_pos, s2_pos, length in blocks: print(f"Match of length {length}: a[{s1_pos}:{s1_pos+length}] == b[{s2_pos}:{s2_pos+length}]") if length > 0: print(f" Matching text: '{a[s1_pos:s1_pos+length]}'") ``` -------------------------------- ### Get Opcodes List Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/types.md Illustrates retrieving edit operations as a list of 5-tuples (opcodes) using the `opcodes` function. This format is suitable for representing blocks of changes (insert, delete, replace, equal) between sequences. ```python from Levenshtein import opcodes # Get opcodes ops: list[tuple[str, int, int, int, int]] = opcodes('spam', 'park') # Result: # ('delete', 0, 1, 0, 0) # ('equal', 1, 3, 0, 2) # ('insert', 3, 3, 2, 3) # ('replace', 3, 4, 3, 4) for operation, s1_start, s1_end, s2_start, s2_end in ops: print(f"{operation}: source[{s1_start}:{s1_end}] -> dest[{s2_start}:{s2_end}]") ``` -------------------------------- ### Quick median with zero weights Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md Demonstrates the behavior of quickmedian when all weights are zero. In this case, an empty string is returned. ```python from Levenshtein import quickmedian result = quickmedian(['tes', 'teste'], wlist=[0, 0]) print(result) # Output: '' (empty string when all weights are zero) ``` -------------------------------- ### Type Hints for Levenshtein Functions Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/README.md Demonstrates how to use type hints with Levenshtein functions for static analysis. Ensure all necessary functions are imported. ```python from Levenshtein import distance, ratio, editops, median from collections.abc import Sequence, Hashable # Type hints work for all functions dist: int = distance("hello", "hallo") sim: float = ratio("hello", "hallo") ops: list[tuple[str, int, int]] = editops("hello", "hallo") result: str = median(["hello", "hallo"]) ``` -------------------------------- ### Initialize StringMatcher Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Create an instance of StringMatcher with initial sequences. ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") ``` -------------------------------- ### Import StringMatcher Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Import the StringMatcher class from the Levenshtein library. ```python from Levenshtein import StringMatcher ``` -------------------------------- ### Standard Module Import Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/README.md Shows the standard way to import the entire Levenshtein module. ```python import Levenshtein ``` -------------------------------- ### Import All Levenshtein Functions and StringMatcher Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/types.md Import all available functions and the StringMatcher class from the Levenshtein library for type checking. ```python from Levenshtein import ( distance, ratio, hamming, jaro, jaro_winkler, editops, opcodes, matching_blocks, apply_edit, subtract_edit, inverse, median, quickmedian, median_improve, setmedian, setratio, seqratio, StringMatcher ) ``` -------------------------------- ### StringMatcher Constructor Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Initialize a StringMatcher object with optional parameters. ```python StringMatcher(isjunk=None, seq1="", seq2="", autojunk=False) ``` -------------------------------- ### Get Edit Operations Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Retrieve the list of edit operations (insert, delete, replace) between the two sequences. The result is cached internally after the first call. ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") editops = matcher.get_editops() print(editops) # Output: [('delete', 0, 0), ('insert', 3, 2), ('replace', 3, 3)] ``` -------------------------------- ### StringMatcher Constructor Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Initializes a StringMatcher instance with optional sequences and junk detection settings. The isjunk and autojunk parameters are kept for compatibility but are not implemented. ```APIDOC ## StringMatcher Constructor ### Description Initialize a StringMatcher instance. ### Signature: ```python class StringMatcher: def __init__( self, isjunk: Callable | None = None, seq1: str = "", seq2: str = "", autojunk: bool = False, ) -> None ``` ### Parameters: | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | isjunk | Callable or None | None | Not implemented. If provided, a warning is issued. Kept for compatibility with difflib.SequenceMatcher. | | seq1 | str | "" | First sequence to compare | | seq2 | str | "" | Second sequence to compare | | autojunk | bool | False | Not implemented. If True, a warning is issued. Kept for compatibility with difflib.SequenceMatcher. | ### Examples: Create a StringMatcher: ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") ``` ``` -------------------------------- ### quick_ratio Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Provides the same ratio calculation as the ratio() method, offered for compatibility with difflib.SequenceMatcher. ```APIDOC ## quick_ratio ### Description Get the ratio (same as ratio() method). This method is provided for compatibility with difflib.SequenceMatcher. It returns the same value as ratio(). ### Signature ```python def quick_ratio(self) -> float ``` ### Returns - **float** — Normalized similarity between 0 and 1, inclusive ### Example ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") sim = matcher.quick_ratio() print(sim) # Same as ratio() ``` ``` -------------------------------- ### quickmedian Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md Provides a fast, approximate generalized median string calculation. This method is a trade-off between speed and accuracy, offering a quicker but potentially less precise result than the standard `median` function. ```APIDOC ## quickmedian ### Description Find a very approximate generalized median string, but fast. This method is somewhere between setmedian() and picking a random string from the set; both speedwise and quality-wise. ### Signature ```python def quickmedian( strlist: list[str | bytes], wlist: list[float] | None = None, ) -> str ``` ### Parameters #### Positional Parameters - **strlist** (list[str or bytes]) - Required - List of strings to compute median from - **wlist** (list[float] or None) - Optional - Optional weights for each string. Any non-negative real numbers are accepted. ### Returns - **str** — An approximate generalized median string, computed much faster than median() ### Raises - **ValueError** — If strlist and wlist have different lengths ``` -------------------------------- ### Show Edit Operations Between Strings Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/USAGE-PATTERNS.md Use `editops` to get a list of operations (insert, delete, replace) to transform one string into another. Useful for diff display and change tracking. ```python from Levenshtein import editops def show_changes(before, after): """Display the changes between two strings.""" ops = editops(before, after) print(f"Transforming '{before}' to '{after}':") for operation, spos, dpos in ops: if operation == 'delete': print(f" - Delete '{before[spos]}' at position {spos}") elif operation == 'insert': print(f" + Insert '{after[dpos]}' at position {dpos}") elif operation == 'replace': print(f" ~ Replace '{before[spos]}' with '{after[dpos]}' at {spos}/{dpos}") show_changes("kitten", "sitting") ``` -------------------------------- ### Levenshtein Import with Type Hints Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Import Levenshtein functions and necessary types for type checking in Python. ```python from Levenshtein import ( distance, ratio, editops, opcodes, median, quickmedian, StringMatcher ) # For type checking from collections.abc import Sequence, Hashable def compare(s1: Sequence[Hashable], s2: Sequence[Hashable]) -> float: return ratio(s1, s2) ``` -------------------------------- ### Selective Module Import Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/README.md Demonstrates importing specific functions from the Levenshtein module for direct use. ```python from Levenshtein import distance, ratio, median, StringMatcher ``` -------------------------------- ### Correct Usage of Keyword-Only Parameters Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Illustrates the correct way to pass keyword-only arguments to functions like distance. These parameters must be specified by name. ```python # ✓ Correct distance(s1, s2, weights=(1, 2, 3)) distance(s1, s2, processor=str.lower) # ✗ Wrong (positional) distance(s1, s2, (1, 2, 3)) ``` -------------------------------- ### Import Version Information Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Import and print version, author, and license information from the Levenshtein module. ```python from Levenshtein import __version__, __author__, __license__ print(__version__) # "0.27.3" print(__author__) # "Max Bachmann" print(__license__) # "GPL" ``` -------------------------------- ### Cache EditOps for Multiple String Comparisons Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/USAGE-PATTERNS.md Cache edit operations for a pair of strings to avoid redundant computations when performing multiple analyses. This is useful when you need to perform several operations (like getting matching blocks or applying edits) on the same source and destination strings. ```python from Levenshtein import editops, matching_blocks, apply_edit class StringComparison: """Cache comparison results for multiple queries.""" def __init__(self, source, destination): self.source = source self.destination = destination self._editops = None @property def editops(self): if self._editops is None: self._editops = editops(self.source, self.destination) return self._editops def get_blocks(self): return matching_blocks(self.editops, self.source, self.destination) def apply(self): return apply_edit(self.editops, self.source, self.destination) def describe_changes(self): return [op for op in self.editops] # Use cached results comp = StringComparison("spam", "park") print(comp.get_blocks()) # Computed once print(comp.describe_changes()) # Reuses same editops ``` -------------------------------- ### Joining Matching Blocks Source: https://github.com/rapidfuzz/levenshtein/blob/main/docs/levenshtein.md Shows how to reconstruct common substrings from matching blocks obtained via editops. ```python >>> a, b = 'dog kennels', 'mattresses' >>> mb = matching_blocks(editops(a,b), a, b) >>> ''.join([a[x[0]:x[0]+x[2]] for x in mb]) 'ees' >>> ''.join([b[x[1]:x[1]+x[2]] for x in mb]) 'ees' ``` -------------------------------- ### Compare Collections of Strings Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/MODULE-OVERVIEW.md Utilize `setratio` for order-independent similarity between two sets of strings and `seqratio` for order-dependent similarity between two sequences of strings. Import both from the Levenshtein module. ```python from Levenshtein import setratio, seqratio list1 = ["cat", "dog", "bird"] list2 = ["car", "dog", "bird"] set_sim = setratio(list1, list2) seq_sim = seqratio(list1, list2) print(f"Set similarity: {set_sim}") print(f"Sequence similarity: {seq_sim}") ``` -------------------------------- ### Opcodes Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Returns a list of opcodes describing how to transform one sequence into another. ```APIDOC ## opcodes(s1, s2) ### Description Returns a list of opcodes describing how to transform one sequence into another. ### Method Not applicable (Python function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **s1** (str) - The first sequence. - **s2** (str) - The second sequence. ### Request Example ```python import Levenshtein ops = Levenshtein.opcodes("apple", "appel") ``` ### Response #### Success Response (list[tuple[str, int, int, int, int]]) - **ops** (list[tuple[str, int, int, int, int]]) - A list of tuples, where each tuple represents an opcode: ('equal', i1, i2, j1, j2), ('insert', i1, i2, j1, j2), ('delete', i1, i2, j1, j2), ('replace', i1, i2, j1, j2). #### Response Example ```json [('equal', 0, 1, 0, 1), ('replace', 1, 5, 1, 5), ('equal', 5, 5, 5, 5)] ``` ``` ```APIDOC ## opcodes(ops, s1_or_len, s2_or_len) ### Description Interprets a list of opcodes or calculates opcodes based on lengths. ### Method Not applicable (Python function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **ops** (list[tuple[str, int, int, int, int]]) - The list of opcodes. - **s1_or_len** (str or int) - The first sequence or its length. - **s2_or_len** (str or int) - The second sequence or its length. ### Request Example ```python import Levenshtein # Example with sequences sequence_ops = [('equal', 0, 1, 0, 1), ('replace', 1, 5, 1, 5)] result = Levenshtein.opcodes(sequence_ops, "apple", "appel") # Example with lengths # result_len = Levenshtein.opcodes(sequence_ops, len("apple"), len("appel")) ``` ### Response #### Success Response (list[tuple[str, int, int, int, int]]) - **result** (list[tuple[str, int, int, int, int]]) - A list of opcodes. #### Response Example ```json [('equal', 0, 1, 0, 1), ('replace', 1, 5, 1, 5)] ``` ``` -------------------------------- ### Apply Edits with Both Editops and Opcodes Formats Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/types.md Demonstrates the flexibility of the `apply_edit` function, which accepts edit operations in either the 3-tuple editops format or the 5-tuple opcodes format. This allows for interchangeable use of different edit representations. ```python from Levenshtein import editops, opcodes, apply_edit source, dest = 'spam', 'park' # Both formats work with apply_edit e = editops(source, dest) o = opcodes(source, dest) # Both can be passed to apply_edit result1 = apply_edit(e, source, dest) # Using editops result2 = apply_edit(o, source, dest) # Using opcodes # Both produce the same result ``` -------------------------------- ### Using weighted strings for median calculation Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md Calculates the median string using weighted inputs. Higher weights, indicated by the wlist parameter, influence the result more significantly. ```python from Levenshtein import median result = median(['cat', 'cat', 'dog'], wlist=[2.0, 2.0, 1.0]) print(result) # 'cat' has higher weight due to appearing multiple times ``` -------------------------------- ### Levenshtein.quickmedian Source: https://github.com/rapidfuzz/levenshtein/blob/main/docs/levenshtein.md Finds a very approximate generalized median string quickly. This method offers a balance between speed and quality, positioned between `setmedian()` and random selection. ```APIDOC ## Levenshtein.quickmedian ### Description Finds a very approximate generalized median string quickly. This method offers a balance between speed and quality, positioned between `setmedian()` and random selection. ### Method Signature `quickmedian(strlist, wlist=None)` ### Parameters * **strlist** (*Sequence*[str]) - Required - List of strings to find the median from. * **wlist** (*Sequence*[float]*, optional) - Optional weights for each string, interpreted as item multiplicities. ### Examples ```pycon >>> fixme = ['Levnhtein', 'Leveshein', 'Leenshten', 'Leveshtei', 'Lenshtein', 'Lvenstein', 'Levenhtin', 'evenshtei'] >>> quickmedian(fixme) 'Levnshein' ``` ``` -------------------------------- ### Find Best Match From List Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/MODULE-OVERVIEW.md Use the `ratio` function within a `max` key to find the string in a list that has the highest similarity to a query string. Import `ratio` from the Levenshtein module. ```python from Levenshtein import ratio candidates = ["apple", "apples", "application", "apply"] query = "apply" best = max(candidates, key=lambda c: ratio(query, c)) print(best) # Output: 'apply' ``` -------------------------------- ### Compute Similarity Ratio for Empty Sets Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md When comparing two empty sets of strings using setratio, the function returns 1.0, indicating a perfect match. ```python from Levenshtein import setratio # When both sets are empty, returns 1.0 (perfect match) ratio = setratio([], []) print(ratio) # Output: 1.0 ``` -------------------------------- ### real_quick_ratio Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Calculates a fast, rough upper bound estimate of the similarity ratio using the formula: 2.0 * min(len1, len2) / (len1 + len2). ```APIDOC ## real_quick_ratio ### Description Get a rough upper bound estimate of the similarity ratio. This is a very fast but crude estimate of the similarity: `2.0 * min(len1, len2) / (len1 + len2)`. ### Signature ```python def real_quick_ratio(self) -> float ``` ### Returns - **float** — A rough upper bound estimate of the similarity ratio ### Example ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") est = matcher.real_quick_ratio() print(est) ``` ``` -------------------------------- ### Compute Similarity Ratio for Empty Sequences Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md When comparing two empty sequences of strings using seqratio, the function returns 1.0, indicating a perfect match. ```python from Levenshtein import seqratio # When both sequences are empty, returns 1.0 (perfect match) ratio = seqratio([], []) print(ratio) # Output: 1.0 ``` -------------------------------- ### String Averaging - Quick Median Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Computes the median string from a list of strings using a quicker algorithm. ```APIDOC ## quickmedian(strlist, wlist=None) ### Description Computes the median string from a list of strings using a quicker algorithm. ### Method Not applicable (Python function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **strlist** (list[str]) - A list of strings. - **wlist** (list[float]) - Optional. A list of weights corresponding to each string in strlist. ### Request Example ```python import Levenshtein strings = ["apple", "banana", "apricot"] quick_median_str = Levenshtein.quickmedian(strings) ``` ### Response #### Success Response (str) - **quick_median_str** (str) - The median string. #### Response Example ```json "apple" ``` ``` -------------------------------- ### Compare Collections Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/README.md Calculate the similarity between collections of strings using `setratio` for unordered sets and `seqratio` for ordered sequences. These functions are useful for comparing lists or sets of items where the order might or might not matter. ```python from Levenshtein import setratio, seqratio list1 = ["cat", "dog", "bird"] list2 = ["car", "dog", "bird"] print(setratio(list1, list2)) # Set similarity print(seqratio(list1, list2)) # Sequence similarity ``` -------------------------------- ### Type Hint Imports for All Functions Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/README.md Imports all available functions from the Levenshtein module, typically used for comprehensive type hinting. ```python from Levenshtein import ( distance, ratio, hamming, jaro, jaro_winkler, editops, opcodes, matching_blocks, apply_edit, subtract_edit, inverse, median, quickmedian, median_improve, setmedian, setratio, seqratio, StringMatcher ) ``` -------------------------------- ### Quick median computation Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md Computes an approximate median string quickly using the quickmedian function. This method is faster but less accurate than the standard median function. ```python from Levenshtein import quickmedian fixme = [ 'Levnhtein', 'Leveshein', 'Leenshten', 'Leveshtei', 'Lenshtein', 'Lvenstein', 'Levenhtin', 'evenshtei' ] result = quickmedian(fixme) print(result) # Output: 'Levnshein' (less accurate than median() but faster) ``` -------------------------------- ### Find Fast Approximate Median String Source: https://github.com/rapidfuzz/levenshtein/blob/main/docs/levenshtein.md Quickly finds a very approximate generalized median string from a list. Offers a balance between speed and quality, similar to setmedian but faster. ```python from rapidfuzz.distance import Levenshtein fixme = ['Levnhtein', 'Leveshein', 'Leenshten', 'Leveshtei', 'Lenshtein', 'Lvenstein', 'Levenhtin', 'evenshtei'] quickmedian(fixme) # Output: 'Levnshein' ``` -------------------------------- ### Batch String Comparison with StringMatcher Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/USAGE-PATTERNS.md Employ `StringMatcher` for efficient comparison of multiple string pairs by reusing matcher state. Useful for integrating with difflib patterns. ```python from Levenshtein import StringMatcher pairs = [ ("apple", "apples"), ("dog", "cat"), ("hello", "hallo"), ] matcher = StringMatcher() for s1, s2 in pairs: matcher.set_seqs(s1, s2) print(f"{s1:10} vs {s2:10}: {matcher.ratio():.2%} similar") ``` -------------------------------- ### Find Approximate Generalized Median String Source: https://github.com/rapidfuzz/levenshtein/blob/main/docs/levenshtein.md Finds an approximate generalized median string from a list of strings using a greedy algorithm. Optionally accepts weights for strings to improve performance. ```python from rapidfuzz.distance import Levenshtein median(['SpSm', 'mpamm', 'Spam', 'Spa', 'Sua', 'hSam']) # Output: 'Spam' ``` ```python from rapidfuzz.distance import Levenshtein fixme = ['Levnhtein', 'Leveshein', 'Leenshten', 'Leveshtei', 'Lenshtein', 'Lvenstein', 'Levenhtin', 'evenshtei'] median(fixme) # Output: 'Levenshtein' ``` -------------------------------- ### StringMatcher Class Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/MODULE-OVERVIEW.md Provides a SequenceMatcher-like interface for string comparison with various methods. ```APIDOC ## StringMatcher ### Description A class that provides a SequenceMatcher-like interface for string comparison. ### Parameters - **isjunk** (callable) - Optional function to identify 'junk' characters. - **seq1** (str) - The first sequence (string). - **seq2** (str) - The second sequence (string). - **autojunk** (bool) - Whether to automatically identify junk characters. ### Methods - **set_seqs(seq1, seq2)**: Sets both sequences for comparison. - **set_seq1(seq1)**: Sets the first sequence. - **set_seq2(seq2)**: Sets the second sequence. - **get_opcodes()**: Returns edit operations in 5-tuple format. - **get_editops()**: Returns edit operations in 3-tuple format. - **get_matching_blocks()**: Returns matching blocks between sequences. - **ratio()**: Returns the normalized similarity ratio. - **quick_ratio()**: Returns a cached similarity ratio. - **real_quick_ratio()**: Returns a rough similarity estimate. - **distance()**: Returns the edit distance. ``` -------------------------------- ### Find median of a list of strings Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md Computes the generalized median string from a list of strings using a greedy algorithm. Weights default to 1.0 if not provided. ```python from Levenshtein import median result = median(['SpSm', 'mpamm', 'Spam', 'Spa', 'Sua', 'hSam']) print(result) # Output: 'Spam' ``` -------------------------------- ### Matching Blocks Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Returns a list of matching blocks between two sequences. ```APIDOC ## matching_blocks(ops, s1_or_len, s2_or_len) ### Description Returns a list of matching blocks between two sequences based on edit operations or lengths. ### Method Not applicable (Python function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **ops** (list[tuple[str, int, int]]) - The list of edit operations. - **s1_or_len** (str or int) - The first sequence or its length. - **s2_or_len** (str or int) - The second sequence or its length. ### Request Example ```python import Levenshtein # First, get edit operations edit_ops = Levenshtein.editops("apple", "appel") # Then, find matching blocks blocks = Levenshtein.matching_blocks(edit_ops, "apple", "appel") ``` ### Response #### Success Response (list[tuple[int, int, int]]) - **blocks** (list[tuple[int, int, int]]) - A list of tuples, where each tuple represents a matching block: (start_in_s1, start_in_s2, length). #### Response Example ```json [(0, 0, 1), (5, 5, 0)] ``` ``` -------------------------------- ### Robust Median String Calculation with Validation Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/USAGE-PATTERNS.md Create a safe function for calculating the median string, including checks for empty input lists, length mismatches between strings and weights, and negative weights. It returns None if validation fails. ```python from Levenshtein import median def safe_median(strings, weights=None): """Safely compute median with validation.""" try: if not strings: raise ValueError("Empty string list") if weights and len(strings) != len(weights): raise ValueError("Length mismatch") if weights and any(w < 0 for w in weights): raise ValueError("Negative weights") return median(strings, weights) except ValueError as e: print(f"Invalid input: {e}") return None ``` -------------------------------- ### Apply Full Edit Operations Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-edit-operations.md Apply a full sequence of edit operations to transform a source string into a destination string. Ensure all edit operations are correctly sequenced. ```python from Levenshtein import editops, apply_edit e = editops('man', 'scotsman') result = apply_edit(e, 'man', 'scotsman') print(result) # Output: 'scotsman' ``` -------------------------------- ### String Averaging (Median) Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/API-EXPORTS.md Functions for calculating approximate generalized medians of string lists. ```APIDOC ## median ### Description Calculates an approximate generalized median string from a list of strings, offering good quality but slower performance. ### Method `median(strlist, wlist=None)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import Levenshtein median_str = Levenshtein.median(["apple", "apricot", "banana"]) ``` ### Response #### Success Response (200) - **median_str** (str) - The calculated median string. #### Response Example ```json { "median_str": "apricot" } ``` ## quickmedian ### Description Calculates a quick approximate median string from a list of strings, prioritizing speed over quality. ### Method `quickmedian(strlist, wlist=None)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import Levenshtein quick_median_str = Levenshtein.quickmedian(["apple", "apricot", "banana"]) ``` ### Response #### Success Response (200) - **quick_median_str** (str) - The calculated quick median string. #### Response Example ```json { "quick_median_str": "apple" } ``` ## median_improve ### Description Improves an existing median estimate using a list of strings and their weights. ### Method `median_improve(string, strlist, wlist=None)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import Levenshtein initial_median = "apricot" strings = ["apple", "apricot", "banana"] improved_median = Levenshtein.median_improve(initial_median, strings) ``` ### Response #### Success Response (200) - **improved_median** (str) - The improved median string. #### Response Example ```json { "improved_median": "apricot" } ``` ## setmedian ### Description Calculates a median string from a set of input strings, ensuring the output is always one of the input strings. ### Method `setmedian(strlist, wlist=None)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import Levenshtein set_median_str = Levenshtein.setmedian(["apple", "apricot", "banana"]) ``` ### Response #### Success Response (200) - **set_median_str** (str) - The median string from the input set. #### Response Example ```json { "set_median_str": "apple" } ``` ``` -------------------------------- ### Find Best Match in Candidate List Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/USAGE-PATTERNS.md Iterate through candidates, calculate similarity ratio, and return matches above a threshold. Ideal for auto-suggest and spell checkers. ```python from Levenshtein import ratio def find_best_match(query, candidates, threshold=0.6): """Find best matching candidate for query.""" matches = [] for candidate in candidates: score = ratio(query, candidate) if score >= threshold: matches.append((candidate, score)) if matches: return sorted(matches, key=lambda x: x[1], reverse=True) return [] # Example usage results = find_best_match("speling", ["spelling", "spelled", "spine"]) for word, score in results: print(f"{word}: {score:.1%}") ``` -------------------------------- ### Set Sequences for StringMatcher Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Update the sequences to be compared in an existing StringMatcher instance. ```python from Levenshtein import StringMatcher matcher = StringMatcher() matcher.set_seqs("spam", "park") ``` -------------------------------- ### Compare Sets of Strings Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/MODULE-OVERVIEW.md Calculates the similarity ratio between two lists of strings, treating them as sets. Requires the `setratio` function. ```python from Levenshtein import setratio group1 = ["apple", "orange", "banana"] group2 = ["apples", "oranges", "grapes"] similarity = setratio(group1, group2) print(f"Set similarity: {similarity:.2%}") # ~72% ``` -------------------------------- ### Spelling Correction using Median Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/USAGE-PATTERNS.md Use `median` or `quickmedian` to find the most representative string from a list of variants. Effective for auto-correcting misspellings. ```python from Levenshtein import median, quickmedian def correct_spelling(misspelled_list): """Correct spelling using median of variants.""" if len(set(misspelled_list)) == 1: return misspelled_list[0] # Try both algorithms, use faster for speed corrected = quickmedian(misspelled_list) return corrected ``` -------------------------------- ### setratio Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md Computes the similarity ratio between two sets of strings. It finds the best match between any strings in the first set and the second set. ```APIDOC ## setratio Compute similarity ratio of two string sets (passed as sequences). The best match between any strings in the first set and the second set is attempted. The order doesn't matter here. Returns a float between 0 and 1 representing the similarity. ### Signature: ```python def setratio( strlist1: list[str | bytes], strlist2: list[str | bytes], ) -> float ``` ### Parameters: | Parameter | Type | Description | |-----------|------|-------------| | strlist1 | list[str or bytes] | First set of strings | | strlist2 | list[str or bytes] | Second set of strings | ### Returns: - **float** — A similarity ratio between 0 and 1 representing the similarity of the two string sets ### Examples: Compare two sets of strings: ```python from Levenshtein import setratio ratio = setratio( ['newspaper', 'litter bin', 'tinny', 'antelope'], ['caribou', 'sausage', 'gorn', 'woody'] ) print(ratio) # Output: 0.2818452380952381 ``` Empty sets: ```python from Levenshtein import setratio # When both sets are empty, returns 1.0 (perfect match) ratio = setratio([], []) print(ratio) # Output: 1.0 ``` ``` -------------------------------- ### seqratio Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-median-averaging.md Computes the similarity ratio between two sequences of strings, using a ratio-based cost for item changes. ```APIDOC ## seqratio Compute similarity ratio of two sequences of strings. This is like ratio(), but for string sequences. A kind of ratio() is used to measure the cost of item change operation for the strings. ### Signature: ```python def seqratio( strlist1: list[str | bytes], strlist2: list[str | bytes], ) -> float ``` ### Parameters: | Parameter | Type | Description | |-----------|------|-------------| | strlist1 | list[str or bytes] | First sequence of strings | | strlist2 | list[str or bytes] | Second sequence of strings | ### Returns: - **float** — A similarity ratio between 0 and 1 representing the similarity of the two string sequences ### Examples: Compare two sequences of strings: ```python from Levenshtein import seqratio ratio = seqratio( ['newspaper', 'litter bin', 'tinny', 'antelope'], ['caribou', 'sausage', 'gorn', 'woody'] ) print(ratio) # Output: 0.21517857142857144 ``` Empty sequences: ```python from Levenshtein import seqratio # When both sequences are empty, returns 1.0 (perfect match) ratio = seqratio([], []) print(ratio) # Output: 1.0 ``` ``` -------------------------------- ### String Averaging (Median) Functions Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/MODULE-OVERVIEW.md Functions to find representative strings (medians) from a set of strings. ```APIDOC ## median ### Description Finds an approximate generalized median string from a list using a greedy algorithm. ### Parameters - **strlist** (list[str]) - A list of strings. - **wlist** (list[float]) - Optional list of weights corresponding to each string in `strlist`. ### Returns - **str**: The approximate median string. ``` ```APIDOC ## quickmedian ### Description Finds an approximate median string from a list very quickly, potentially with lower quality than `median`. ### Parameters - **strlist** (list[str]) - A list of strings. - **wlist** (list[float]) - Optional list of weights corresponding to each string in `strlist`. ### Returns - **str**: The approximate median string. ``` ```APIDOC ## median_improve ### Description Improves an existing estimated median string by applying perturbations based on a list of strings. ### Parameters - **string** (str) - The current estimated median string. - **strlist** (list[str]) - A list of strings to refine the median against. - **wlist** (list[float]) - Optional list of weights corresponding to each string in `strlist`. ### Returns - **str**: The improved median string. ``` ```APIDOC ## setmedian ### Description Finds a median string from an input set, always returning one of the input strings. ### Parameters - **strlist** (list[str]) - A list of strings. - **wlist** (list[float]) - Optional list of weights corresponding to each string in `strlist`. ### Returns - **str**: A median string from the input set. ``` -------------------------------- ### Custom Operation Costs with Weights Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/MODULE-OVERVIEW.md Define custom costs for insertion, deletion, and substitution operations using the weights parameter. ```python from Levenshtein import distance # Make substitutions more expensive result = distance("a", "b", weights=(1, 1, 10)) print(result) # Output: 10 (substitution cost) ``` -------------------------------- ### Set First Sequence Source: https://github.com/rapidfuzz/levenshtein/blob/main/_autodocs/api-reference-string-matcher.md Modify the first sequence of a StringMatcher instance. ```python from Levenshtein import StringMatcher matcher = StringMatcher(seq1="spam", seq2="park") matcher.set_seq1("spaz") ```