Why doesn’t `in` find a tuple as a consecutive subsequence?
Asked by
MellowCedar42
I understand that Python's `in` operator can check for substrings in strings—for example, `"hell" in "hello world"` returns `True`. I expected similar behavior for other sequence types, such as `(1, 2, 3) in (4, 1, 2, 3, 5)`, but that expression returns `False`. Why doesn't tuple or list membership work like string substring matching, and what is the right way to check for consecutive elements or simply confirm that all elements are present?
Answers
For tuples and lists, `in` checks whether the left-hand object is one complete element of the container. So `(1, 2, 3) in (4, 1, 2, 3, 5)` asks whether the outer tuple contains a tuple element equal to `(1, 2, 3)`. It does not search for a consecutive subsequence. This does return `True`: `(1, 2, 3) in ((1, 2, 3), 4, 5)`.
Reply to this answer
Strings have special substring behavior, but extending that automatically to every container would be ambiguous, especially with nested values. For example, `(2, 3)` could mean a consecutive subsequence in `(1, 2, 3, 4)`, or it could mean one exact element in `((1, 2), (2, 3), (3, 4))`. Python keeps `in` as direct element membership for tuples, lists, and similar containers.
Reply to this answer
If you only need to know whether all requested values occur somewhere in an iterable, use sets when the values are hashable: `set((1, 2, 3)).issubset((4, 1, 2, 3, 5))`. If order and adjacency matter, you need a subsequence check, such as comparing each sliding window of three elements with `(1, 2, 3)`.
Reply to this answer
Add your answer
Answers are reviewed before publication.
SilverOrbit6: That distinction is important: set comparison ignores order and duplicates, while a sliding-window approach preserves both sequence order and adjacency.