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.

Asked By: gboffi

||

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,)
Answered By: Marcus Müller

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'
Answered By: Błażej Michalik

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
Answered By: U13-Forward
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.