の*
ようなコードzip(*x)
やのようなPythonでの演算子の意味は何f(**k)
ですか?
- インタプリタの内部でどのように処理されますか?
- パフォーマンスにまったく影響しますか?速いですか遅いですか?
- いつ役に立ち、いつ役に立たないのですか?
- 関数宣言または呼び出しで使用する必要がありますか?
の*
ようなコードzip(*x)
やのようなPythonでの演算子の意味は何f(**k)
ですか?
*
**
[*a, b, *c]
または{**d1, **d2}
)の場合、タプルのアスタリスク、リストとセットの定義、dict定義の二重アスタリスクを読む必要があります。これは関数呼び出しと関数定義以外の使用に固有です。。以前のPEP3132については、シーケンスの長さがわからない場合のPythonでの複数の解凍割り当てを参照してください。
回答:
単一の星*
は、シーケンス/コレクションを位置引数に解凍するため、次のことができます。
def sum(a, b):
return a + b
values = (1, 2)
s = sum(*values)
これにより、タプルが解凍され、実際には次のように実行されます。
s = sum(1, 2)
二重星**
は同じことを行いますが、辞書と名前付き引数のみを使用します。
values = { 'a': 1, 'b': 2 }
s = sum(**values)
以下を組み合わせることもできます。
def sum(a, b, c, d):
return a + b + c + d
values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sum(*values1, **values2)
次のように実行されます:
s = sum(1, 2, c=10, d=15)
セクション4.7.4- Pythonドキュメントの引数リストの解凍も参照してください。
さらに、取る関数*x
と**y
引数を定義できます。これにより、関数は、宣言で具体的に指定されていない任意の数の位置引数や名前付き引数を受け入れることができます。
例:
def sum(*values):
s = 0
for v in values:
s = s + v
return s
s = sum(1, 2, 3, 4, 5)
またはと**
:
def get_a(**values):
return values['a']
s = get_a(a=1, b=2) # returns 1
これにより、宣言せずに多数のオプションパラメータを指定できます。
そして再び、あなたは組み合わせることができます:
def sum(*values, **options):
s = 0
for i in values:
s = s + i
if "neg" in options:
if options["neg"]:
s = -s
return s
s = sum(1, 2, 3, 4, 5) # returns 15
s = sum(1, 2, 3, 4, 5, neg=True) # returns -15
s = sum(1, 2, 3, 4, 5, neg=False) # returns 15
s = sum((1, 2, 3, 4, 5))
またはs = sum([1, 2, 3, 4, 5])
、この*values
オプションを使用すると、呼び出しはいくつかの引数を取るように見えますが、それらは関数コードのコレクションにパックされています。
1つの小さなポイント:これらは演算子ではありません。演算子は、既存の値から新しい値を作成するために式で使用されます(たとえば、1 + 2は3になります。ここでの*と**は、関数宣言と呼び出しの構文の一部です。
これは、関数呼び出しを「保存」する場合に特に便利です。
たとえば、関数 'add'の単体テストがあるとします。
def add(a, b): return a + b
tests = { (1,4):5, (0, 0):0, (-1, 3):3 }
for test, result in tests.items():
print 'test: adding', test, '==', result, '---', add(*test) == result
add(test [0]、test [1])のような醜いことを手動で行う以外に、addを呼び出す方法はありません。また、変数の数が可変である場合、必要なすべてのifステートメントでコードがかなり醜くなる可能性があります。
これが役立つもう1つの場所は、ファクトリオブジェクト(オブジェクトを作成するオブジェクト)を定義する場合です。Carオブジェクトを作成して返すクラスFactoryがあるとします。myFactory.make_car( 'red'、 'bmw'、 '335ix')がCar( 'red'、 'bmw'、 '335ix')を作成し、それを返すようにすることができます。
def make_car(*args):
return Car(*args)
これは、スーパークラスのコンストラクターを呼び出す場合にも役立ちます。
これは、拡張呼び出し構文と呼ばれます。ドキュメントから:
構文* expressionが関数呼び出しに含まれている場合、expressionはシーケンスに評価される必要があります。このシーケンスの要素は、追加の位置引数であるかのように扱われます。位置引数x1、...、xNがあり、式がシーケンスy1、...、yMに評価される場合、これはM + N位置引数x1、...、xN、y1、...を使用した呼び出しと同等です。 ..、yM。
そして:
構文**式が関数呼び出しに含まれている場合、式はマッピングに評価される必要があり、その内容は追加のキーワード引数として扱われます。式と明示的なキーワード引数の両方にキーワードが表示される場合、TypeError例外が発生します。
apply()
機能
関数呼び出しでは、単一の星は、(例えば別々の引数にリストを回すzip(*x)
と同じであるzip(x1,x2,x3)
場合はx=[x1,x2,x3]
例えば()と二重星は、別々のキーワード引数に辞書を回すf(**k)
と同じであるf(x=my_x, y=my_y)
場合k = {'x':my_x, 'y':my_y}
。
関数定義では、その逆です。単一のスターは任意の数の引数をリストに変換し、ダブルスタートは任意の数のキーワード引数を辞書に変換します。たとえばdef foo(*x)
、「fooは任意の数の引数を取り、リストxからアクセスできます(つまり、ユーザーがを呼び出すとfoo(1,2,3)
、にx
なります[1,2,3]
)」をdef bar(**k)
意味し、「barは任意の数のキーワード引数を取り、辞書kからアクセスできる」ことを意味します。 (ユーザー・コール場合、すなわちbar(x=42, y=23)
、k
だろう{'x': 42, 'y': 23}
「)。
def foo(*x)
* xからはリストではなくタプルが得られると思います。