web-dev-qa-db-ja.com

Python:Splat / unpack演算子* pythonは式で使用できませんか?

誰かが、単項(*)演算子がイテレータ/リスト/タプルを含む式で使用できない理由に関する理由を知っていますか?

なぜそれが機能のアンパックに限定されているのですか?それとも私はそれを間違っていると思いますか?

例えば:

>>> [1,2,3, *[4,5,6]]
File "<stdin>", line 1
[1,2,3, *[4,5,6]]
        ^
SyntaxError: invalid syntax

*演算子を使用しない理由:

[1, 2, 3, *[4, 5, 6]] give [1, 2, 3, 4, 5, 6]

一方、*演算子を関数呼び出しで使用すると、次のように展開されます。

f(*[4, 5, 6]) is equivalent to f(4, 5, 6)

リストを使用する場合、+*は類似していますが、別のタイプでリストを拡張する場合は類似していません。

例えば:

# This works
gen = (x for x in range(10))

def hello(*args):
    print args    
hello(*gen)

# but this does not work
[] + gen
TypeError: can only concatenate list (not "generator") to list
25
Har

で説明されているように、リスト、辞書、セット、およびタプルリテラルのアンパックがPython 3.5に追加されました。 PEP 448

Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) on Windows (64 bits).

>>> [1, 2, 3, *[4, 5, 6]]
[1, 2, 3, 4, 5, 6]

こちら は、この変更の背後にある理論的根拠の説明です。これにより、すべてのコンテキストで*[1, 2, 3]1, 2, 3と等価になるわけではないことに注意してください。 Pythonの構文は、そのように機能することを意図していません。

38
B. M.

アステリックス*は単純な単項演算子ではなく、 関数定義 および-の引数展開演算子です。 関数呼び出し

そう *のみを使用することになっています関数のパラメーターを操作するためにを使用しないでくださいリスト、タプルなど.

注:python3.5以降、*は関数paramsだけでなく、 @ B。M でも使用できますが、これはpythonの変更点を大きく説明しています。

リストを連結する必要がある場合は、代わりに連結を使用してくださいlist1 + list2希望の結果を取得します。リストとgeneratorを連結するには、generatorlistタイプのオブジェクトに渡してから、別のリストと連結します。

gen = (x for x in range(10))
[] + list(gen)
5
Andriy Ivaneyko

これはサポートされていません。 Python 3はより良いメッセージを提供します(ただし、Python 2は割り当ての左側の_*_をサポートしていませんが、afaik):

_Python 3.4.3+ (default, Oct 14 2015, 16:03:50) 
>>> [1,2,3, *[4,5,6]]
  File "<stdin>", line 1
SyntaxError: can use starred expression only as assignment target
>>> 
_

f(*[4,5,6])f(4,5,6)と同等です

関数引数の展開は特殊なケースです。

3
warvariuc