SyntaxError with starred expression when unpacking a tuple on its own for string formatting
Question:
I tried the following using the REPL in Python 3.5.2:
>>> a = (1, 2)
>>> '%d %d %d' % (0, *a)
'0 1 2'
>>> '%d %d %d' % (*a, 3)
'1 2 3'
>>> '%d %d' % (*a)
File "<stdin>", line 1
SyntaxError: can't use starred expression here
>>>
My question, why?
In a more serious tone: I’d like an answer, or a reference, that details all the ins and outs of using a starred expression, as it happens that I am sometimes surprised from its behaviours…
Addendum
To reflect some of the enlightening comments that
immediately followed my question I add the following code
>>> '%d %d' % (, *a)
File "<stdin>", line 1
'%d %d' % (, *a)
^
SyntaxError: invalid syntax
>>> '%d %d' % (*a,)
'1 2'
>>>
(I had tried the (, a)
part before posting the original question but I’ve omitted it ’cause the error was not related to the starring.)
There is a syntax, in python ≥ 3.5, that "just works" but nevertheless I would like some understanding.
Answers:
My question, why?
Because your python syntax doesn’t allow that. It’s defined that way, so there’s no real “why”.
also, it’s unnecessary.
"%d %d" % a
would work.
So, you’d need to convert your expansion to a tuple – and the right way of doing that would be, as pointed out by Lafexlos, be
"%d %d" % (*a,)
The error occurs because (a)
is just a value surrounded by parenthesis. It’s not a new tuple object.
Thus, '%d %d' % (*a)
is equivalent to '%d %d' % * a
, which is obviously wrong in terms of python syntax.
To create a new tuple, with one expression as an initializer, use a comma after that expression:
>>> '%d %d' % (*a,)
'1 2'
Of course, since a
is already a tuple, we can use it directly:
>>> '%d %d' % a
'1 2'
It’s because:
>>> '%d %d' % (*a)
Can be just:
>>> '%d %d' %a
Of course then able to do:
>>> '%d %d' % (*a,)
But then:
>>> (*a,)==a
True
>>>
Or you can do:
>>> '%d %d' % [*a]
But then:
>>> [*a]
[1, 2]
>>> a
(1, 2)
>>>
So:
>>> tuple([*a])==a
True
I tried the following using the REPL in Python 3.5.2:
>>> a = (1, 2)
>>> '%d %d %d' % (0, *a)
'0 1 2'
>>> '%d %d %d' % (*a, 3)
'1 2 3'
>>> '%d %d' % (*a)
File "<stdin>", line 1
SyntaxError: can't use starred expression here
>>>
My question, why?
In a more serious tone: I’d like an answer, or a reference, that details all the ins and outs of using a starred expression, as it happens that I am sometimes surprised from its behaviours…
Addendum
To reflect some of the enlightening comments that
immediately followed my question I add the following code
>>> '%d %d' % (, *a)
File "<stdin>", line 1
'%d %d' % (, *a)
^
SyntaxError: invalid syntax
>>> '%d %d' % (*a,)
'1 2'
>>>
(I had tried the (, a)
part before posting the original question but I’ve omitted it ’cause the error was not related to the starring.)
There is a syntax, in python ≥ 3.5, that "just works" but nevertheless I would like some understanding.
My question, why?
Because your python syntax doesn’t allow that. It’s defined that way, so there’s no real “why”.
also, it’s unnecessary.
"%d %d" % a
would work.
So, you’d need to convert your expansion to a tuple – and the right way of doing that would be, as pointed out by Lafexlos, be
"%d %d" % (*a,)
The error occurs because (a)
is just a value surrounded by parenthesis. It’s not a new tuple object.
Thus, '%d %d' % (*a)
is equivalent to '%d %d' % * a
, which is obviously wrong in terms of python syntax.
To create a new tuple, with one expression as an initializer, use a comma after that expression:
>>> '%d %d' % (*a,)
'1 2'
Of course, since a
is already a tuple, we can use it directly:
>>> '%d %d' % a
'1 2'
It’s because:
>>> '%d %d' % (*a)
Can be just:
>>> '%d %d' %a
Of course then able to do:
>>> '%d %d' % (*a,)
But then:
>>> (*a,)==a
True
>>>
Or you can do:
>>> '%d %d' % [*a]
But then:
>>> [*a]
[1, 2]
>>> a
(1, 2)
>>>
So:
>>> tuple([*a])==a
True