jonohashmo
jonohashmo

Reputation: 33

Is this tuple syntax inside a Python list-comprehension? If not, what is it?

I am having some trouble understanding parts of syntax. Particularly when parentheses () are required for tuples.

For instance, this piece of code below:

c = {'a':10,'b':1,'c':22,'d':10}

tup = a,b = 4,5

print(a)
print(b)
print(tup)

newlist = [(x,y) for y,x in c.items()]

print(newlist)

The output for this code is:

4
5
(4, 5)
[(10, 'a'), (1, 'b'), (22, 'c'), (10, 'd')]

When trying to take the parentheses out of x, y in the list comprehension statement, I get a traceback. However, every other tuple in this code does not require parenthesis.

What am I missing? Why is it that Python understands a,b to be a tuple but not x,y when it is in a list comprehension statement?

It seems to me that Python is inconsistent with tuple syntax. I tried taking the parentheses out and putting them back to understand how the syntax works.

Upvotes: 3

Views: 147

Answers (1)

Stef
Stef

Reputation: 15525

Parentheses are needed to give priority to operators. Consider the two following lines of code, which differ only by the parentheses:

tup_a = 3, 4 + 10, 20
tup_b = (3, 4) + (10, 20)

The first line defines a tuple tup_a of 3 elements, (3, 14, 20). The second line defines two tuples (3, 4) and (10, 20), then concatenates them into a tuple of four elements, (3, 4, 10, 20).

Wrong parentheses can easily result in an error:

tup_c = 3, 4 * 10, 20
tup_d = (3, 4) * (10, 20)

The first line defines a tuple of 3 elements, (3, 40, 20). The second line results in a TypeError because it defines two tuples (3, 4) and (10, 20) and then attempts to multiply them, but the multiplication operator * doesn't know what to do with tuples.

You encountered a similar issue. Consider the following lines of codes:

x = 42
c = {'a': 10, 'b': 1, 'c': 22, 'd': 10}

l_a = [(x, y) for y,x in c.items()]  # [(10, 'a'), (1, 'b'), (22, 'c'), (10, 'd')]
l_b = [x, (y for y,x in c.items())]  # [42, <generator object>]
l_c = [x, y for y,x in c.items()]    # SyntaxError: invalid syntax

This code correctly defines two lists l_a and l_b, but then it raises a SyntaxError when trying to define l_c.

The designers of python decided that the syntax for l_c was ambiguous, and you should add parentheses to explicitly specify whether you meant the same thing as l_a or as l_b.

Note that the line of code for l_b would raise a NameError: name 'x' is not defined if I hadn't added x = 42 at the beginning, since the role of x is not the same in l_b as it is in l_a.

Upvotes: 9

Related Questions