1717
1818--------------
1919
20- This module provides classes and functions for comparing sequences. It
21- can be used for example, for comparing files, and can produce information
22- about file differences in various formats, including HTML and context and unified
23- diffs. For comparing directories and files, see also, the :mod: `filecmp ` module.
24-
25-
26- .. class :: SequenceMatcher
27- :noindex:
28-
29- This is a flexible class for comparing pairs of sequences of any type, so long
30- as the sequence elements are :term: `hashable `. The basic algorithm predates, and is a
31- little fancier than, an algorithm published in the late 1980's by Ratcliff and
32- Obershelp under the hyperbolic name "gestalt pattern matching." The idea is to
33- find the longest contiguous matching subsequence that contains no "junk"
34- elements; these "junk" elements are ones that are uninteresting in some
35- sense, such as blank lines or whitespace. (Handling junk is an
36- extension to the Ratcliff and Obershelp algorithm.) The same
37- idea is then applied recursively to the pieces of the sequences to the left and
38- to the right of the matching subsequence. This does not yield minimal edit
39- sequences, but does tend to yield matches that "look right" to people.
40-
41- **Timing: ** The basic Ratcliff-Obershelp algorithm is cubic time in the worst
42- case and quadratic time in the expected case. :class: `SequenceMatcher ` is
43- quadratic time for the worst case and has expected-case behavior dependent in a
44- complicated way on how many elements the sequences have in common; best case
45- time is linear.
46-
47- **Junk **: :class: `SequenceMatcher ` accepts an ``isjunk `` predicate and an
48- ``autojunk `` flag. Items that are considered as junk will not be considered
49- to find similar content blocks. This can produce better results for humans
50- (typically breaking on whitespace) and faster (because it reduces the number
51- of possible combinations). But it can also cause pathological cases where
52- too many items considered junk cause an unexpectedly large (but correct)
53- diff result.
54- You should consider tuning them or turning them off depending on your data.
55- Moreover, only the second sequence is inspected for junk. This causes the diff
56- output to not be symmetrical.
57- When ``autojunk=True ``, it will consider as junk the items that account for more
58- than 1% of the sequence, if it is at least 200 items long.
20+ This module provides classes and functions for comparing sequences.
21+ Most of them compare sequences of text lines (for example lists of strings,
22+ or :term: `file objects <file object> `) and
23+ produce :dfn: `diffs ` -- reports on the differences.
24+ Diffs can be produced in in various formats, including HTML and context
25+ and unified diffs -- formats produced by tools like
26+ :manpage: `diff <diff(1)>` and :manpage: `git diff <git-diff(1)>`.
5927
60- .. versionchanged :: 3.2
61- Added the *autojunk * parameter.
28+ Comparisons are done using a matching algorithm implemented in
29+ :class: `SequenceMatcher ` -- a flexible class for comparing pairs of sequences
30+ of any type, not just text, so long as the sequence elements are
31+ :term: `hashable `.
32+
33+
34+ .. _difflib-junk :
35+
36+ Junk heuristic
37+ --------------
38+
39+ :mod: `!difflib ` uses a :dfn: `junk ` heuristic: some items are deemed to be
40+ :dfn: `junk `, and ignored when searching for similarities.
41+ Ideally, these are uninteresting or common items, such as blank lines
42+ or whitespace.
43+
44+ This heuristic can speed the algorithm up (because it reduces the number of
45+ possible combinations) and it can produce results that are more understandable
46+ for humans (typically breaking on whitespace).
47+ But it can also cause pathological cases:
48+
49+ - Inappropriately chosen junk items can cause an unexpectedly **large ** (but
50+ still correct) result.
51+ - The default heuristic is **asymmetric **: only the second sequence is
52+ inspected when determining what is considered junk, so comparing A to B can
53+ give different results than comparing B to A and reversing the result.
54+
55+ By default, if the second input sequence is at least 200 items long, items
56+ that account for more than 1% it are considered *junk *.
57+
58+ Depending on your data, you should consider turning this heuristic off
59+ (setting :class: `~difflib.SequenceMatcher `'s *autojunk * argument to to ``False ``)
60+ or tuning it (using the *isjunk * argument, perhaps to one of the
61+ :ref: `predefined functions <difflib-isjunk-functions >`).
62+
63+
64+ The :mod: `!difflib ` algorithm
65+ -----------------------------
66+
67+ The algorithm used in :class: `SequenceMatcher ` predates, and is a little
68+ fancier than, an algorithm published in the late 1980s by Ratcliff and
69+ Obershelp under the hyperbolic name "gestalt pattern matching."
70+ The idea is to find the longest contiguous subsequence common to both inputs,
71+ then recursively handle the pieces of the sequences to the left and to the
72+ right of the matching subsequence.
73+
74+ .. seealso ::
75+
76+ `Pattern Matching: The Gestalt Approach <https://jacobfilipp.com/DrDobbs/articles/DDJ/1988/8807/8807c/8807c.htm >`_
77+ Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This
78+ was published in Dr. Dobb's Journal in July, 1988.
79+
80+ As an extension to the Ratcliff and Obershelp algorithm, :mod: `!difflib `
81+ searches for the longest *junk-free * contiguous subsequence.
82+ See the :ref: `difflib-junk ` section for details.
83+
84+ .. impl-detail :: Timing
6285
86+ The basic Ratcliff-Obershelp algorithm is cubic time in the worst
87+ case and quadratic time in the expected case.
88+ :mod: `difflib `'s algorithm is quadratic time for the worst case and has
89+ expected-case behavior dependent in a complicated way on how many elements
90+ the sequences have in common;
91+ best case time is linear.
92+
93+
94+ .. _difflib-diff-generation :
95+
96+ Diff generation
97+ ---------------
98+
99+ .. _differ-objects :
63100
64101.. class :: Differ
65102
@@ -86,6 +123,47 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
86123 and were not present in either input sequence. These lines can be confusing if
87124 the sequences contain whitespace characters, such as spaces, tabs or line breaks.
88125
126+ Note that :class: `Differ `\ -generated deltas make no claim to be **minimal **
127+ diffs. To the contrary, minimal diffs are often counter-intuitive for humans,
128+ because they synch up anywhere possible, sometimes at accidental matches
129+ 100 pages apart.
130+ Restricting synch points to contiguous matches preserves some notion of
131+ locality, at the occasional cost of producing a longer diff.
132+
133+ The :class: `Differ ` class has this constructor:
134+
135+ .. method :: __init__(linejunk=None, charjunk=None)
136+
137+ Optional keyword parameters *linejunk * and *charjunk * are for filter functions
138+ (or ``None ``):
139+
140+ *linejunk *: A function that accepts a single string argument, and returns true
141+ if the string is junk. The default is ``None ``, meaning that no line is
142+ considered junk.
143+
144+ *charjunk *: A function that accepts a single character argument (a string of
145+ length 1), and returns true if the character is junk. The default is ``None ``,
146+ meaning that no character is considered junk.
147+
148+ These junk-filtering functions speed up matching to find
149+ differences and do not cause any differing lines or characters to
150+ be ignored. Read the description of the
151+ :meth: `~SequenceMatcher.find_longest_match ` method's *isjunk *
152+ parameter for an explanation.
153+
154+ :class: `Differ ` objects are used (deltas generated) via a single method:
155+
156+
157+ .. method :: Differ.compare(a, b)
158+
159+ Compare two sequences of lines, and generate the delta (a sequence of lines).
160+
161+ Each sequence must contain individual single-line strings ending with
162+ newlines. Such sequences can be obtained from the
163+ :meth: `~io.IOBase.readlines ` method of file-like objects. The generated
164+ delta also consists of newline-terminated strings, ready to be
165+ printed as-is via the :meth: `~io.IOBase.writelines ` method of a
166+ file-like object.
89167
90168.. class :: HtmlDiff
91169
@@ -345,6 +423,12 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
345423
346424 .. versionadded :: 3.5
347425
426+
427+ .. _difflib-isjunk-functions :
428+
429+ Junk definition functions
430+ -------------------------
431+
348432.. function :: IS_LINE_JUNK(line)
349433
350434 Return ``True `` for ignorable lines. The line *line * is ignorable if *line * is
@@ -359,21 +443,11 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module.
359443 parameter *charjunk * in :func: `ndiff `.
360444
361445
362- .. seealso ::
363-
364- `Pattern Matching: The Gestalt Approach <https://jacobfilipp.com/DrDobbs/articles/DDJ/1988/8807/8807c/8807c.htm >`_
365- Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This
366- was published in Dr. Dobb's Journal in July, 1988.
367-
368-
369446.. _sequence-matcher :
370447
371448SequenceMatcher objects
372449-----------------------
373450
374- The :class: `SequenceMatcher ` class has this constructor:
375-
376-
377451.. class :: SequenceMatcher(isjunk=None, a='', b='', autojunk=True)
378452
379453 Optional argument *isjunk * must be ``None `` (the default) or a one-argument
@@ -584,10 +658,13 @@ are always at least as large as :meth:`~SequenceMatcher.ratio`:
584658 1.0
585659
586660
661+ Examples
662+ --------
663+
587664.. _sequencematcher-examples :
588665
589666SequenceMatcher examples
590- ------------------------
667+ ........................
591668
592669This example compares two strings, considering blanks to be "junk":
593670
@@ -635,59 +712,10 @@ If you want to know how to change the first sequence into the second, use
635712 built with :class: `SequenceMatcher `.
636713
637714
638- .. _differ-objects :
639-
640- Differ objects
641- --------------
642-
643- Note that :class: `Differ `\ -generated deltas make no claim to be **minimal **
644- diffs. To the contrary, minimal diffs are often counter-intuitive, because they
645- synch up anywhere possible, sometimes accidental matches 100 pages apart.
646- Restricting synch points to contiguous matches preserves some notion of
647- locality, at the occasional cost of producing a longer diff.
648-
649- The :class: `Differ ` class has this constructor:
650-
651-
652- .. class :: Differ(linejunk=None, charjunk=None)
653- :noindex:
654-
655- Optional keyword parameters *linejunk * and *charjunk * are for filter functions
656- (or ``None ``):
657-
658- *linejunk *: A function that accepts a single string argument, and returns true
659- if the string is junk. The default is ``None ``, meaning that no line is
660- considered junk.
661-
662- *charjunk *: A function that accepts a single character argument (a string of
663- length 1), and returns true if the character is junk. The default is ``None ``,
664- meaning that no character is considered junk.
665-
666- These junk-filtering functions speed up matching to find
667- differences and do not cause any differing lines or characters to
668- be ignored. Read the description of the
669- :meth: `~SequenceMatcher.find_longest_match ` method's *isjunk *
670- parameter for an explanation.
671-
672- :class: `Differ ` objects are used (deltas generated) via a single method:
673-
674-
675- .. method :: Differ.compare(a, b)
676-
677- Compare two sequences of lines, and generate the delta (a sequence of lines).
678-
679- Each sequence must contain individual single-line strings ending with
680- newlines. Such sequences can be obtained from the
681- :meth: `~io.IOBase.readlines ` method of file-like objects. The delta
682- generated also consists of newline-terminated strings, ready to be
683- printed as-is via the :meth: `~io.IOBase.writelines ` method of a
684- file-like object.
685-
686-
687715.. _differ-examples :
688716
689717Differ example
690- --------------
718+ ..............
691719
692720This example compares two texts. First we set up the texts, sequences of
693721individual single-line strings ending with newlines (such sequences can also be
@@ -754,14 +782,14 @@ As a single multi-line string it looks like this:
754782.. _difflib-interface :
755783
756784A command-line interface to difflib
757- -----------------------------------
785+ ...................................
758786
759787This example shows how to use difflib to create a ``diff ``-like utility.
760788
761789.. literalinclude :: ../includes/diff.py
762790
763791ndiff example
764- -------------
792+ .............
765793
766794This example shows how to use :func: `difflib.ndiff `.
767795
0 commit comments