Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I will just leave it here #338

Open
raaymax opened this issue Jun 20, 2024 · 3 comments
Open

I will just leave it here #338

raaymax opened this issue Jun 20, 2024 · 3 comments

Comments

@raaymax
Copy link

raaymax commented Jun 20, 2024

>>> "asd" in ("asd")
True
>>> "asd" in ("asd", "zxc")
True
>>> "asd" in ("asdzxc")
True
>>> "asd" in ("asdzxc", "zxc")
False
@fabianoengler
Copy link

fabianoengler commented Jun 20, 2024

Explanation

Short explanation

Tuples are created by the comma syntax, not the parentheses. Parentheses are used only to adjust operator precedence.


Long explanation:

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
@suroorhussain
Copy link

>>> ("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"

@nifadyev
Copy link
Contributor

Hey @fabianoengler , do you mind making a PR? Your explanation is filled with context and quite easy to understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants