47

以下はPythonで美しく機能します。

def f(x,y,z): return [x,y,z]

a=[1,2]

f(3,*a)

の要素はa、まるであなたがそれを好きなように呼んだかのように解凍されf(3,1,2)、それは戻ります[3,1,2]。素晴らしい!

しかし、の要素を最初の2つの引数にアンパックすることはできaませ

f(*a,3)

のように呼び出す代わりに、f(1,2,3)「SyntaxError:名前付き引数のみが*expressionの後に続く可能性があります」というメッセージが表示されます。

なぜそれがそのようでなければならないのか疑問に思っています。一時変数に頼らずに配列を引数リストの任意の部分に解凍するための巧妙なトリックがある場合は気付かないかもしれません。

4

6 に答える 6

37

Raymond Hettinger の回答が指摘しているように、これは変更される可能性があり、Python 3 で変更されました。これは、承認された関連する提案です。特に現在の質問に関連して、議論されたその提案に対する可能な変更の1つを次に示します。

exprlist の最後の項目としてスター付きの式のみを許可します。これにより、アンパック コードが少し簡素化され、スター付きの式に反復子を割り当てることができます。この振る舞いはあまりにも驚くべきものであるため、却下されました。

したがって、関数の引数のアンパックに関する制限には実装上の理由がありますが、実際には少し驚くべきことです!

それまでの間、私が探していた回避策は次のとおりです。振り返ってみると明らかです。

f(*(a+[3]))
于 2012-10-10T23:31:45.830 に答える
12

そうである必要はありません。グイドが賢明だと思ったのは、ただの規則でした。

Python 3 では、アンパックのルールがいくらか自由化されました。

>>> a, *b, c = range(10)
>>> a
0
>>> b
[1, 2, 3, 4, 5, 6, 7, 8]
>>> c
9

Guido が言語を改善すると感じるかどうかに応じて、その自由化は関数の引数にも拡張できます。

Python 3 でルールが変更された理由については、拡張された iterable unpackingに関する議論を参照してください。

于 2012-10-04T05:07:03.800 に答える
12

PEP 448 - Additional Unpacking Generalizationsのおかげで、

f(*a, 3)

Python 3.5 から始まる構文として受け入れられるようになりました。同様に、どこでもキーワード引数のアンパックに二重星**を使用でき、いずれかを複数回使用できます。

于 2015-09-22T13:25:09.490 に答える
4

fは3つの引数(、、、、この順序で)を期待してxいますyz

と仮定しL = [1,2]ます。を呼び出すときf(3, *L)、Pythonが舞台裏で行うf(3, 1, 2)ことは、の長さを実際に知らなくても、を呼び出すことですL

Lでは、代わりにだったらどうなる[1,2,3]でしょうか?

次に、を呼び出すとf(3, *L)、を呼び出すことになります。これは、正確に3つの引数を期待していて、4を指定しf(3,1,2,3)たため、エラーになります。f

ここで、L=[1,2]1. Look at what happens when you callf`を想定します。

>>> f(3,*L) # works fine
>>> f(*L) # will give you an error when f(1,2) is called; insufficient arguments

f(*L, 3)これで、 3を呼び出すと暗黙的にわかりますzが、pythonはそれを認識しません。j入力の最後の多くの要素がfの内容によって定義されることだけを知っていLます。ただし、の値がわからないため、引数の数が正しいlen(L)かどうかを推測することはできません。f(*L,3)

ただし、これは。の場合には当てはまりませんf(3,*L)。この場合、Pythonは、最初の引数を除くすべての引数が。の内容によって定義されることを認識していますL

ただし、引数f(x=1, y=2, z=3)に名前を付けた場合は、名前で割り当てられている引数が最初にバインドされます。そうして初めて、位置引数がバインドされます。だからあなたはしますf(*L, z=3)。その場合、zは最初にバインドされ3、次に他の値がバインドされます。

興味深いことに、これを行った場合、2回f(*L, y=3)割り当てようとするとエラーが発生しますy(1回はキーワードで、もう1回は位置で)

お役に立てれば

于 2012-10-04T05:09:29.543 に答える
2

良い。これはタプルでも機能します。コンマを忘れないでください:

a = (1,2)
f(*(a+(3,)))
于 2013-08-29T20:43:30.833 に答える