diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 583bf78d1649b60..af61bee0eaf51c3 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -316,11 +316,19 @@ Diff generation Setting the optional *autojunk* argument to ``False`` will turn :ref:`automatic junk heuristic ` off. + Optional arg *key* (default ``None``) specifies a function of one argument that + is used to extract a comparison key from each element in *possibilities* + (for example, ``key=str.lower``). If the value is ``None``, the elements are + compared with *word* directly. + The best (no more than *n*) matches among the possibilities are returned in a list, sorted by similarity score, most similar first. >>> get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy']) ['apple', 'ape'] + >>> get_close_matches("appel", [("aple", 9), ("peach", 8), ("puppy", 7)], + ... key=lambda x: x[0]) + [('aple', 9)] >>> import keyword >>> get_close_matches('wheel', keyword.kwlist) ['while'] diff --git a/Lib/difflib.py b/Lib/difflib.py index 54fc57db975b252..6f778945f2a2796 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1,7 +1,7 @@ """ Module difflib -- helpers for computing deltas between objects. -Function get_close_matches(word, possibilities, n=3, cutoff=0.6): +Function get_close_matches(word, possibilities, n=3, cutoff=0.6, key=None): Use SequenceMatcher to return list of the best "good enough" matches. Function context_diff(a, b): @@ -664,7 +664,8 @@ def real_quick_ratio(self): __class_getitem__ = classmethod(GenericAlias) -def get_close_matches(word, possibilities, n=3, cutoff=0.6, *, autojunk=True): +def get_close_matches(word, possibilities, n=3, cutoff=0.6, key=None, *, + autojunk=True): """Use SequenceMatcher to return list of the best "good enough" matches. word is a sequence for which close matches are desired (typically a @@ -679,11 +680,18 @@ def get_close_matches(word, possibilities, n=3, cutoff=0.6, *, autojunk=True): Optional arg cutoff (default 0.6) is a float in [0, 1]. Possibilities that don't score at least that similar to word are ignored. + Optional arg key specifies a function of one argument that is used to + extract a comparison key from each element in iterable (for example, + key=str.lower). The default value is None (compare the elements directly). + The best (no more than n) matches among the possibilities are returned in a list, sorted by similarity score, most similar first. >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"]) ['apple', 'ape'] + >>> get_close_matches("appel", [("aple", 9), ("peach", 8), ("puppy", 7)], + ... key=lambda x: x[0]) + [('aple', 9)] >>> import keyword as _keyword >>> get_close_matches("wheel", _keyword.kwlist) ['while'] @@ -701,7 +709,7 @@ def get_close_matches(word, possibilities, n=3, cutoff=0.6, *, autojunk=True): s = SequenceMatcher(autojunk=autojunk) s.set_seq2(word) for x in possibilities: - s.set_seq1(x) + s.set_seq1(key(x) if key is not None else x) if s.real_quick_ratio() < cutoff or s.quick_ratio() < cutoff: continue diff --git a/Misc/NEWS.d/next/Library/2021-05-16-16-46-01.bpo-44149.2MUHbG.rst b/Misc/NEWS.d/next/Library/2021-05-16-16-46-01.bpo-44149.2MUHbG.rst new file mode 100644 index 000000000000000..af7f92f3649a5a2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-05-16-16-46-01.bpo-44149.2MUHbG.rst @@ -0,0 +1 @@ +Add a ``key`` argument to :func:`difflib.get_close_matches`. \ No newline at end of file