pythontuplesmatchoperator-keyword

Python operate 'in' on tuple won't match by whole word


It seems the operator 'in' on tuple won't only match the whole string if there is only one item in the tuple. The behavior is different from 'list' and 'set'. I don't understand where the difference is coming from, it's by design to have some specific usage or it's a bug?

Python 3.12.3 (tags/v3.12.3:f6650f9, Apr  9 2024, 14:05:25) [MSC v.1938 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> skip_funcs = ("ENG_EN1")          # mis-match in tuple
>>> "ENG" in skip_funcs
True
>>> skip_funcs = ("ENG_EN1", "abc")   # correct if the tuple has more than one component
>>> "ENG" in skip_funcs
False
>>> "ENG_EN1" in skip_funcs
True
>>> skip_funcs = ["ENG_EN1"]          # correct for 'list'
>>> "ENG" in skip_funcs
False
>>> "ENG_EN1" in skip_funcs
True
>>> skip_funcs = {"ENG_EN1"}          # correct for 'set'
>>> "ENG" in skip_funcs
False
>>> "ENG_EN1" in skip_funcs
True

Solution

  • skip_funcs = ("ENG_EN1")
    

    does not define a tuple, but :

    skip_funcs = ("ENG_EN1",)
    

    Does.

    As in mathematics, parentheses in Python are also used to define priority operations. So, when you write (“ENG_EN1”), you're asking Python to evaluate what's inside the parenthesis first, i.e. “ENG_EN1” (which, in your case, isn't very useful). So, in python

    skip_funcs = ("ENG_EN1")
    

    Is equivalent to :

    skip_funcs = "ENG_EN1"
    

    So skip_funcs is a string. So :

    "ENG" in skip_funcs 
    

    returns True.

    To differentiate between parentheses used to define a priority, and parentheses used to define a tuple, a comma is required. In your case, you should write :

    skip_funcs = ("ENG_EN1",)