Open raaymax opened 3 months ago
Tuples are created by the comma syntax, not the parentheses. Parentheses are used only to adjust operator precedence.
This is a substring test:
>>> "asd" in "asd"
True
Same as:
>>> "asd" in "asdzxc"
True
>>> "asd" in "zxcvbn"
False
Adding parentheses (round brackets) doesn't make it a tuple, the result of the expression is still a string:
>>> "asd" in ("asdzxc")
True
>>> expression = ("asdzxc")
>>> type(expression)
<class 'str'>
Parentheses are used for forcing expression evaluation precedence. In fact, it's common to use this syntax to construct a long string by using multiple lines of code (which triggers implicit string concatenation):
>>> "asd" in ("zxca"
... "sd")
True
>>> expression = ("zxca"
... "sd")
>>> type(expression)
<class 'str'>
What actually creates a tuple is the comma character, not the parentheses. In fact, you don't need parentheses to create a tuple:
>>> "asd", "zxc"
('asd', 'zxc')
>>> expression = "asd", "zxc"
>>> expression
('asd', 'zxc')
>>> type(expression)
<class 'tuple'>
The expression "asd" in "asd", "zxc"
is totally valid, it does create a tuple, but probably not the one you intended:
>>> "asd" in "asd", "zxc"
(True, 'zxc')
What happens here is that the in
operator has higher precedence than the comma ,
operator, so the expression evaluates the in
first ("asd" in "asd"
), which results in True
, than create the tuple with True
and "zxc"
.
If you really really wanted that, it's probably a good idea to add a redundant parentheses just to make the intent of the code clear:
>>> ("asd" in "asd"), "zxc"
(True, 'zxc')
But usually what you want is for the "asd", "zxc"
to be the tuple, in that case you need parentheses just to adjust the operator precedence for the desired effect:
>>> "asd" in ("asd", "zxc")
True
Since it's the comma syntax that creates the tuple (and not the parentheses), to create a tuple with a single element only, you still need a comma to create the tuple:
>>> "asd"
'asd'
>>> "asd",
('asd',)
But even with a single element tuple, if you want to test the tuple with in
operator, you still need the parentheses to adjust the precedence or you get the tuple after the in
test:
>>> "asd" in "asd",
(True,)
# the above is equivalent to:
>>> ("asd" in "asd"),
(True,)
For the desired result, you need parentheses to adjust the operator precedence:
>>> "asd" in ("asd",)
True
If you omit the comma, it's not a tuple anymore, but a simple string:
# substring test:
>>> "asd" in ("asdzxc")
True
# same as:
>>> "asd" in "asdzxc"
True
# element inside tuple test:
>>> "asd" in ("asdzxc",)
False
Now the the whole original WTF code should make sense:
>>> "asd" in ("asd") # substring test
True
>>> "asd" in ("asd", "zxc") # element inside tuple test:
True
>>> "asd" in ("asdzxc") # substring test
True
>>> "asd" in ("asdzxc", "zxc") # element inside tuple test:
False
>>> ("asdzxc")
'asdzxc'
>>> ("asdzxc", "zxc")
('asdzxc', 'zxc')
>>> ("asdzxc",)
('asdzxc',)
>>> "asd" in ("asdzxc",)
False
Tuples in python are created using the comma , not paranthesis - so ("asdzxc")
is just "asdzxc"