Reputation: 33
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
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