Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
A single element tuple has a trailing comma Note that the example in the question does not form a tuple, as there is a special syntax for single element tuples. A single element tuple has a traili...
Answer
#2: Post edited
- ## A single element tuple has a trailing comma
- Note that the example in the question does not form a tuple, as there is a special syntax for single element tuples. A single element tuple has a trailing comma after its single element. This is necessary to distinguish the single element tuple from an expression that has been enclosed in parentheses to control the order of calculation.
- ```python
a = (1) # a == 1 (not a tuple)b = (1,) # b == (1,) (a tuple)- ```
- This allows writing the following to control order of calculation, without accidentally making `(1 + 1)` a tuple:
- ```python
- c = 2 * (1 + 1) # c == 4
- ```
- ## No problem with `if`
- An `if` block starts with a line of the following form:
- ```python
- if expression:
- ```
- Here `expression` can be any expression that Python can evaluate to a boolean (True or False). Wrapping an expression in parentheses does not make it a tuple, due to it lacking the required trailing comma for a single element tuple. The enclosing parentheses are therefore interpreted as affecting the order of calculation. Since they enclose the entire expression, there is nothing else to calculate afterwards, so they have no effect. The following 2 lines are therefore equivalent:
- ```python
- if 1 + 1 == 2:
- ```
- ```python
- if (1 + 1 == 2):
- ```
- ## Problem with `for`
- A `for` block starts with a line of the following form:
- ```python
- for variable in iterable:
- ```
- Here `variable` is any valid Python variable name[^1], and `iterable` is any valid Python expression that evaluates to something that can be iterated over.
- As before, an expression enclosed in parentheses is equivalent to the original expression, so the following 2 lines are equivalent:
- ```python
for value in [1, 2, 3]:- ```
- ```python
for value in ([1, 2, 3]):- ```
- In the same way, enclosing a variable in parentheses has no effect, so the following 2 lines are equivalent:
- ```python
for value in [1, 2, 3]:- ```
- ```python
for (value) in [1, 2, 3]:- ```
The problem is caused by also enclosing the `in` in parentheses. This causes `(value in [1, 2, 3])` to be interpreted as a single expression. This is the cause of the invalid syntax that Python complains about:- ```python
for (value in [1, 2, 3]):- ```
- is interpreted as the invalid
- ```python
- for expression:
- ```
- instead of
- ```python
- for variable in iterable:
- ```
- ## Different meaning of `in` when not part of a `for` loop
When the parentheses make `in` part of a separate expression `(value in [1, 2, 3])`, rather than part of the `for` loop, `in` takes on its other meaning in Python: Checking for presence of an item in a container.- ```python
2 in [1, 2, 3] # True4 in [1, 2, 3] # False- ```
- [^1]: This is oversimplified to keep the explanation brief - there can in fact be several variables in a single `for` loop, potentially including several layers of destructuring. This is omitted here as it is not relevant to why the parentheses cause a problem.
- ## A single element tuple has a trailing comma
- Note that the example in the question does not form a tuple, as there is a special syntax for single element tuples. A single element tuple has a trailing comma after its single element. This is necessary to distinguish the single element tuple from an expression that has been enclosed in parentheses to control the order of calculation.
- ```python
- a = (1) # a == 1 (not a tuple)
- b = (1,) # b == (1,) (a tuple)
- ```
- This allows writing the following to control order of calculation, without accidentally making `(1 + 1)` a tuple:
- ```python
- c = 2 * (1 + 1) # c == 4
- ```
- ## No problem with `if`
- An `if` block starts with a line of the following form:
- ```python
- if expression:
- ```
- Here `expression` can be any expression that Python can evaluate to a boolean (True or False). Wrapping an expression in parentheses does not make it a tuple, due to it lacking the required trailing comma for a single element tuple. The enclosing parentheses are therefore interpreted as affecting the order of calculation. Since they enclose the entire expression, there is nothing else to calculate afterwards, so they have no effect. The following 2 lines are therefore equivalent:
- ```python
- if 1 + 1 == 2:
- ```
- ```python
- if (1 + 1 == 2):
- ```
- ## Problem with `for`
- A `for` block starts with a line of the following form:
- ```python
- for variable in iterable:
- ```
- Here `variable` is any valid Python variable name[^1], and `iterable` is any valid Python expression that evaluates to something that can be iterated over.
- As before, an expression enclosed in parentheses is equivalent to the original expression, so the following 2 lines are equivalent:
- ```python
- for fruit in ["Apple", "Banana", "Orange"]:
- ```
- ```python
- for fruit in (["Apple", "Banana", "Orange"]):
- ```
- In the same way, enclosing a variable in parentheses has no effect, so the following 2 lines are equivalent:
- ```python
- for fruit in ["Apple", "Banana", "Orange"]:
- ```
- ```python
- for (fruit) in ["Apple", "Banana", "Orange"]:
- ```
- The problem is caused by also enclosing the `in` in parentheses. This causes `(fruit in ["Apple", "Banana", "Orange"])` to be interpreted as a single expression. This is the cause of the invalid syntax that Python complains about:
- ```python
- for (fruit in ["Apple", "Banana", "Orange"]):
- ```
- is interpreted as the invalid
- ```python
- for expression:
- ```
- instead of
- ```python
- for variable in iterable:
- ```
- ## Different meaning of `in` when not part of a `for` loop
- When the parentheses make `in` part of a separate expression `(fruit in ["Apple", "Banana", "Orange"])`, rather than part of the `for` loop, `in` takes on its other meaning in Python: Checking for presence of an item in a container.
- ```python
- "Banana" in ["Apple", "Banana", "Orange"] # True
- "Grape" in ["Apple", "Banana", "Orange"] # False
- ```
- [^1]: This is oversimplified to keep the explanation brief - there can in fact be several variables in a single `for` loop, potentially including several layers of destructuring. This is omitted here as it is not relevant to why the parentheses cause a problem.
#1: Initial revision
## A single element tuple has a trailing comma Note that the example in the question does not form a tuple, as there is a special syntax for single element tuples. A single element tuple has a trailing comma after its single element. This is necessary to distinguish the single element tuple from an expression that has been enclosed in parentheses to control the order of calculation. ```python a = (1) # a == 1 (not a tuple) b = (1,) # b == (1,) (a tuple) ``` This allows writing the following to control order of calculation, without accidentally making `(1 + 1)` a tuple: ```python c = 2 * (1 + 1) # c == 4 ``` ## No problem with `if` An `if` block starts with a line of the following form: ```python if expression: ``` Here `expression` can be any expression that Python can evaluate to a boolean (True or False). Wrapping an expression in parentheses does not make it a tuple, due to it lacking the required trailing comma for a single element tuple. The enclosing parentheses are therefore interpreted as affecting the order of calculation. Since they enclose the entire expression, there is nothing else to calculate afterwards, so they have no effect. The following 2 lines are therefore equivalent: ```python if 1 + 1 == 2: ``` ```python if (1 + 1 == 2): ``` ## Problem with `for` A `for` block starts with a line of the following form: ```python for variable in iterable: ``` Here `variable` is any valid Python variable name[^1], and `iterable` is any valid Python expression that evaluates to something that can be iterated over. As before, an expression enclosed in parentheses is equivalent to the original expression, so the following 2 lines are equivalent: ```python for value in [1, 2, 3]: ``` ```python for value in ([1, 2, 3]): ``` In the same way, enclosing a variable in parentheses has no effect, so the following 2 lines are equivalent: ```python for value in [1, 2, 3]: ``` ```python for (value) in [1, 2, 3]: ``` The problem is caused by also enclosing the `in` in parentheses. This causes `(value in [1, 2, 3])` to be interpreted as a single expression. This is the cause of the invalid syntax that Python complains about: ```python for (value in [1, 2, 3]): ``` is interpreted as the invalid ```python for expression: ``` instead of ```python for variable in iterable: ``` ## Different meaning of `in` when not part of a `for` loop When the parentheses make `in` part of a separate expression `(value in [1, 2, 3])`, rather than part of the `for` loop, `in` takes on its other meaning in Python: Checking for presence of an item in a container. ```python 2 in [1, 2, 3] # True 4 in [1, 2, 3] # False ``` [^1]: This is oversimplified to keep the explanation brief - there can in fact be several variables in a single `for` loop, potentially including several layers of destructuring. This is omitted here as it is not relevant to why the parentheses cause a problem.