Why can't I use a starred expression?

风流意气都作罢 提交于 2019-11-29 22:20:31

It's because this:

(a)

Is just a value surrounded by parenthesis. It's not a new tuple object. So your expression:

>>> '%d %d' % (*a)

will get translated to:

>>> '%d %d' % * a

which is obviously wrong in terms of python syntax.

In order to create a new Tuple, with one expression as an initializer, you need to add a ',' after it:

>>> '%d %d' % (*a,)

Note: unless a is a generator, in this particular situation you could just type:

>>> '%d %d' % a

Also, if I may suggest something: you could start using new-style formating expressions. They are great!

>>> "{} {}".format(*a)

You can read more about them in those two paragraphs of python documentation, also there is this great website. The line above uses argument unpacking mechanism described below.

Starred Expressions

There are many more uses to starred expression than just creating a new list/tuple/dictionary. Most of them are described in this PEP, and this one

All of them come down to two kinds:

RValue unpacking:

>>> a, *b, c = range(5)
# a = 0
# b = [1, 2, 3]
# c = 4
>>> 10, *range(2)
(10, 0, 1)

Iterable / dictionary object initialization (notice that you can unpack dictionaries inside lists too!):

>>> [1, 2, *[3, 4], *[5], *(6, 7)]
[1, 2, 3, 4, 5, 6, 7]
>>> (1, *[2, 3], *{"a": 1})
(1, 2, 3, 'a')
>>> {"a": 1, **{"b": 2, "c": 3}, **{"c": "new 3", "d": 4}}
{'a': 1, 'b': 2, 'c': 'new 3', 'd': 4}

Of course, the most often seen use is arguments unpacking:

positional_arguments = [12, "a string", (1, 2, 3), other_object]
keyword_arguments = {"hostname": "localhost", "port": 8080}
send(*positional_arguments, **keyword_arguments)

which would translate to this:

send(12, "a string", (1, 2, 3), other_object, hostname="localhost", port=8080)

This topic was already covered in great extent in another Stack Overflow question.

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,)

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!