Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

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

71%
+3 −0
Q&A Why can parentheses cause exceptions in Python when using for loops?

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...

posted 1y ago by trichoplax‭  ·  edited 1y ago by trichoplax‭

Answer
#2: Post edited by user avatar trichoplax‭ · 2023-04-17T00:37:17Z (about 1 year ago)
Make examples consistent with the question example
  • ## 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.
  • ## 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 by user avatar trichoplax‭ · 2023-04-17T00:28:20Z (about 1 year ago)
## 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.